blob: d5a1b8fe434f85ee8b92f8921b7fc0191dfbddba [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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800741
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700742 final RemoteCallbackList<IActivityWatcher> mWatchers
743 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700744
745 final RemoteCallbackList<IProcessObserver> mProcessObservers
746 = new RemoteCallbackList<IProcessObserver>();
747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 /**
749 * Callback of last caller to {@link #requestPss}.
750 */
751 Runnable mRequestPssCallback;
752
753 /**
754 * Remaining processes for which we are waiting results from the last
755 * call to {@link #requestPss}.
756 */
757 final ArrayList<ProcessRecord> mRequestPssList
758 = new ArrayList<ProcessRecord>();
759
760 /**
761 * Runtime statistics collection thread. This object's lock is used to
762 * protect all related state.
763 */
764 final Thread mProcessStatsThread;
765
766 /**
767 * Used to collect process stats when showing not responding dialog.
768 * Protected by mProcessStatsThread.
769 */
770 final ProcessStats mProcessStats = new ProcessStats(
771 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700772 final AtomicLong mLastCpuTime = new AtomicLong(0);
773 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 long mLastWriteTime = 0;
776
777 /**
778 * Set to true after the system has finished booting.
779 */
780 boolean mBooted = false;
781
Dianne Hackborn7d608422011-08-07 16:24:18 -0700782 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700783 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784
785 WindowManagerService mWindowManager;
786
787 static ActivityManagerService mSelf;
788 static ActivityThread mSystemThread;
789
790 private final class AppDeathRecipient implements IBinder.DeathRecipient {
791 final ProcessRecord mApp;
792 final int mPid;
793 final IApplicationThread mAppThread;
794
795 AppDeathRecipient(ProcessRecord app, int pid,
796 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800797 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 TAG, "New death recipient " + this
799 + " for thread " + thread.asBinder());
800 mApp = app;
801 mPid = pid;
802 mAppThread = thread;
803 }
804
805 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800806 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 TAG, "Death received in " + this
808 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 synchronized(ActivityManagerService.this) {
810 appDiedLocked(mApp, mPid, mAppThread);
811 }
812 }
813 }
814
815 static final int SHOW_ERROR_MSG = 1;
816 static final int SHOW_NOT_RESPONDING_MSG = 2;
817 static final int SHOW_FACTORY_ERROR_MSG = 3;
818 static final int UPDATE_CONFIGURATION_MSG = 4;
819 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
820 static final int WAIT_FOR_DEBUGGER_MSG = 6;
821 static final int BROADCAST_INTENT_MSG = 7;
822 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 static final int SERVICE_TIMEOUT_MSG = 12;
824 static final int UPDATE_TIME_ZONE = 13;
825 static final int SHOW_UID_ERROR_MSG = 14;
826 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700828 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700829 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800830 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700831 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
832 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700833 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700834 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700835 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700836 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700837 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700838 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
839 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840
841 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700842 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800843
844 final Handler mHandler = new Handler() {
845 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800846 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 //}
848
849 public void handleMessage(Message msg) {
850 switch (msg.what) {
851 case SHOW_ERROR_MSG: {
852 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 synchronized (ActivityManagerService.this) {
854 ProcessRecord proc = (ProcessRecord)data.get("app");
855 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800856 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800857 return;
858 }
859 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700860 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800861 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 d.show();
863 proc.crashDialog = d;
864 } else {
865 // The device is asleep, so just pretend that the user
866 // saw a crash dialog and hit "force quit".
867 res.set(0);
868 }
869 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700870
871 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 } break;
873 case SHOW_NOT_RESPONDING_MSG: {
874 synchronized (ActivityManagerService.this) {
875 HashMap data = (HashMap) msg.obj;
876 ProcessRecord proc = (ProcessRecord)data.get("app");
877 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800878 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879 return;
880 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800881
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700882 Intent intent = new Intent("android.intent.action.ANR");
883 if (!mProcessesReady) {
884 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
885 }
886 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800887 null, null, 0, null, null, null,
888 false, false, MY_PID, Process.SYSTEM_UID);
889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800890 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700891 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 d.show();
893 proc.anrDialog = d;
894 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700895
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700896 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700898 case SHOW_STRICT_MODE_VIOLATION_MSG: {
899 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
900 synchronized (ActivityManagerService.this) {
901 ProcessRecord proc = (ProcessRecord) data.get("app");
902 if (proc == null) {
903 Slog.e(TAG, "App not found when showing strict mode dialog.");
904 break;
905 }
906 if (proc.crashDialog != null) {
907 Slog.e(TAG, "App already has strict mode dialog: " + proc);
908 return;
909 }
910 AppErrorResult res = (AppErrorResult) data.get("result");
911 if (!mSleeping && !mShuttingDown) {
912 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
913 d.show();
914 proc.crashDialog = d;
915 } else {
916 // The device is asleep, so just pretend that the user
917 // saw a crash dialog and hit "force quit".
918 res.set(0);
919 }
920 }
921 ensureBootCompleted();
922 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 case SHOW_FACTORY_ERROR_MSG: {
924 Dialog d = new FactoryErrorDialog(
925 mContext, msg.getData().getCharSequence("msg"));
926 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700927 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 } break;
929 case UPDATE_CONFIGURATION_MSG: {
930 final ContentResolver resolver = mContext.getContentResolver();
931 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
932 } break;
933 case GC_BACKGROUND_PROCESSES_MSG: {
934 synchronized (ActivityManagerService.this) {
935 performAppGcsIfAppropriateLocked();
936 }
937 } break;
938 case WAIT_FOR_DEBUGGER_MSG: {
939 synchronized (ActivityManagerService.this) {
940 ProcessRecord app = (ProcessRecord)msg.obj;
941 if (msg.arg1 != 0) {
942 if (!app.waitedForDebugger) {
943 Dialog d = new AppWaitingForDebuggerDialog(
944 ActivityManagerService.this,
945 mContext, app);
946 app.waitDialog = d;
947 app.waitedForDebugger = true;
948 d.show();
949 }
950 } else {
951 if (app.waitDialog != null) {
952 app.waitDialog.dismiss();
953 app.waitDialog = null;
954 }
955 }
956 }
957 } break;
958 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800959 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 TAG, "Received BROADCAST_INTENT_MSG");
961 processNextBroadcast(true);
962 } break;
963 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700964 synchronized (ActivityManagerService.this) {
965 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800967 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700969 if (mDidDexOpt) {
970 mDidDexOpt = false;
971 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
972 nmsg.obj = msg.obj;
973 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
974 return;
975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 serviceTimeout((ProcessRecord)msg.obj);
977 } break;
978 case UPDATE_TIME_ZONE: {
979 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800980 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
981 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 if (r.thread != null) {
983 try {
984 r.thread.updateTimeZone();
985 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800986 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 }
988 }
989 }
990 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700991 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700992 case CLEAR_DNS_CACHE: {
993 synchronized (ActivityManagerService.this) {
994 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
995 ProcessRecord r = mLruProcesses.get(i);
996 if (r.thread != null) {
997 try {
998 r.thread.clearDnsCache();
999 } catch (RemoteException ex) {
1000 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1001 }
1002 }
1003 }
1004 }
1005 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001006 case UPDATE_HTTP_PROXY: {
1007 ProxyProperties proxy = (ProxyProperties)msg.obj;
1008 String host = "";
1009 String port = "";
1010 String exclList = "";
1011 if (proxy != null) {
1012 host = proxy.getHost();
1013 port = Integer.toString(proxy.getPort());
1014 exclList = proxy.getExclusionList();
1015 }
1016 synchronized (ActivityManagerService.this) {
1017 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1018 ProcessRecord r = mLruProcesses.get(i);
1019 if (r.thread != null) {
1020 try {
1021 r.thread.setHttpProxy(host, port, exclList);
1022 } catch (RemoteException ex) {
1023 Slog.w(TAG, "Failed to update http proxy for: " +
1024 r.info.processName);
1025 }
1026 }
1027 }
1028 }
1029 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 case SHOW_UID_ERROR_MSG: {
1031 // XXX This is a temporary dialog, no need to localize.
1032 AlertDialog d = new BaseErrorDialog(mContext);
1033 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1034 d.setCancelable(false);
1035 d.setTitle("System UIDs Inconsistent");
1036 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 +02001037 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001038 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1039 mUidAlert = d;
1040 d.show();
1041 } break;
1042 case IM_FEELING_LUCKY_MSG: {
1043 if (mUidAlert != null) {
1044 mUidAlert.dismiss();
1045 mUidAlert = null;
1046 }
1047 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001049 if (mDidDexOpt) {
1050 mDidDexOpt = false;
1051 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1052 nmsg.obj = msg.obj;
1053 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1054 return;
1055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056 ProcessRecord app = (ProcessRecord)msg.obj;
1057 synchronized (ActivityManagerService.this) {
1058 processStartTimedOutLocked(app);
1059 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001060 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001061 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1062 synchronized (ActivityManagerService.this) {
1063 doPendingActivityLaunchesLocked(true);
1064 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001065 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001066 case KILL_APPLICATION_MSG: {
1067 synchronized (ActivityManagerService.this) {
1068 int uid = msg.arg1;
1069 boolean restart = (msg.arg2 == 1);
1070 String pkg = (String) msg.obj;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001071 forceStopPackageLocked(pkg, uid, restart, false, true);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001072 }
1073 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001074 case FINALIZE_PENDING_INTENT_MSG: {
1075 ((PendingIntentRecord)msg.obj).completeFinalize();
1076 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001077 case POST_HEAVY_NOTIFICATION_MSG: {
1078 INotificationManager inm = NotificationManager.getService();
1079 if (inm == null) {
1080 return;
1081 }
1082
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001083 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001084 ProcessRecord process = root.app;
1085 if (process == null) {
1086 return;
1087 }
1088
1089 try {
1090 Context context = mContext.createPackageContext(process.info.packageName, 0);
1091 String text = mContext.getString(R.string.heavy_weight_notification,
1092 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1093 Notification notification = new Notification();
1094 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1095 notification.when = 0;
1096 notification.flags = Notification.FLAG_ONGOING_EVENT;
1097 notification.tickerText = text;
1098 notification.defaults = 0; // please be quiet
1099 notification.sound = null;
1100 notification.vibrate = null;
1101 notification.setLatestEventInfo(context, text,
1102 mContext.getText(R.string.heavy_weight_notification_detail),
1103 PendingIntent.getActivity(mContext, 0, root.intent,
1104 PendingIntent.FLAG_CANCEL_CURRENT));
1105
1106 try {
1107 int[] outId = new int[1];
1108 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1109 notification, outId);
1110 } catch (RuntimeException e) {
1111 Slog.w(ActivityManagerService.TAG,
1112 "Error showing notification for heavy-weight app", e);
1113 } catch (RemoteException e) {
1114 }
1115 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001116 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001117 }
1118 } break;
1119 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1120 INotificationManager inm = NotificationManager.getService();
1121 if (inm == null) {
1122 return;
1123 }
1124 try {
1125 inm.cancelNotification("android",
1126 R.string.heavy_weight_notification);
1127 } catch (RuntimeException e) {
1128 Slog.w(ActivityManagerService.TAG,
1129 "Error canceling notification for service", e);
1130 } catch (RemoteException e) {
1131 }
1132 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001133 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1134 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001135 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001136 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001137 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1138 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001139 }
1140 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001141 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1142 synchronized (ActivityManagerService.this) {
1143 ActivityRecord ar = (ActivityRecord)msg.obj;
1144 if (mCompatModeDialog != null) {
1145 if (mCompatModeDialog.mAppInfo.packageName.equals(
1146 ar.info.applicationInfo.packageName)) {
1147 return;
1148 }
1149 mCompatModeDialog.dismiss();
1150 mCompatModeDialog = null;
1151 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001152 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001153 if (mCompatModePackages.getPackageAskCompatModeLocked(
1154 ar.packageName)) {
1155 int mode = mCompatModePackages.computeCompatModeLocked(
1156 ar.info.applicationInfo);
1157 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1158 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1159 mCompatModeDialog = new CompatModeDialog(
1160 ActivityManagerService.this, mContext,
1161 ar.info.applicationInfo);
1162 mCompatModeDialog.show();
1163 }
1164 }
1165 }
1166 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001167 break;
1168 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001169 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001170 final int pid = msg.arg1;
1171 final int uid = msg.arg2;
1172 final boolean foregroundActivities = (Boolean) msg.obj;
1173 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001174 break;
1175 }
1176 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001177 final int pid = msg.arg1;
1178 final int uid = msg.arg2;
1179 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001180 break;
1181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 }
1183 }
1184 };
1185
1186 public static void setSystemProcess() {
1187 try {
1188 ActivityManagerService m = mSelf;
1189
1190 ServiceManager.addService("activity", m);
1191 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001192 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 if (MONITOR_CPU_USAGE) {
1194 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196 ServiceManager.addService("permission", new PermissionController(m));
1197
1198 ApplicationInfo info =
1199 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001200 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001201 mSystemThread.installSystemApplicationInfo(info);
1202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 synchronized (mSelf) {
1204 ProcessRecord app = mSelf.newProcessRecordLocked(
1205 mSystemThread.getApplicationThread(), info,
1206 info.processName);
1207 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001208 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001209 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1211 synchronized (mSelf.mPidsSelfLocked) {
1212 mSelf.mPidsSelfLocked.put(app.pid, app);
1213 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001214 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001215 }
1216 } catch (PackageManager.NameNotFoundException e) {
1217 throw new RuntimeException(
1218 "Unable to find android system package", e);
1219 }
1220 }
1221
1222 public void setWindowManager(WindowManagerService wm) {
1223 mWindowManager = wm;
1224 }
1225
1226 public static final Context main(int factoryTest) {
1227 AThread thr = new AThread();
1228 thr.start();
1229
1230 synchronized (thr) {
1231 while (thr.mService == null) {
1232 try {
1233 thr.wait();
1234 } catch (InterruptedException e) {
1235 }
1236 }
1237 }
1238
1239 ActivityManagerService m = thr.mService;
1240 mSelf = m;
1241 ActivityThread at = ActivityThread.systemMain();
1242 mSystemThread = at;
1243 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001244 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 m.mContext = context;
1246 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001247 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248
1249 m.mBatteryStatsService.publish(context);
1250 m.mUsageStatsService.publish(context);
1251
1252 synchronized (thr) {
1253 thr.mReady = true;
1254 thr.notifyAll();
1255 }
1256
1257 m.startRunning(null, null, null, null);
1258
1259 return context;
1260 }
1261
1262 public static ActivityManagerService self() {
1263 return mSelf;
1264 }
1265
1266 static class AThread extends Thread {
1267 ActivityManagerService mService;
1268 boolean mReady = false;
1269
1270 public AThread() {
1271 super("ActivityManager");
1272 }
1273
1274 public void run() {
1275 Looper.prepare();
1276
1277 android.os.Process.setThreadPriority(
1278 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001279 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280
1281 ActivityManagerService m = new ActivityManagerService();
1282
1283 synchronized (this) {
1284 mService = m;
1285 notifyAll();
1286 }
1287
1288 synchronized (this) {
1289 while (!mReady) {
1290 try {
1291 wait();
1292 } catch (InterruptedException e) {
1293 }
1294 }
1295 }
1296
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001297 // For debug builds, log event loop stalls to dropbox for analysis.
1298 if (StrictMode.conditionallyEnableDebugLogging()) {
1299 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1300 }
1301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 Looper.loop();
1303 }
1304 }
1305
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 static class MemBinder extends Binder {
1307 ActivityManagerService mActivityManagerService;
1308 MemBinder(ActivityManagerService activityManagerService) {
1309 mActivityManagerService = activityManagerService;
1310 }
1311
1312 @Override
1313 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001314 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 }
1316 }
1317
Chet Haase9c1e23b2011-03-24 10:51:31 -07001318 static class GraphicsBinder extends Binder {
1319 ActivityManagerService mActivityManagerService;
1320 GraphicsBinder(ActivityManagerService activityManagerService) {
1321 mActivityManagerService = activityManagerService;
1322 }
1323
1324 @Override
1325 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001326 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001327 }
1328 }
1329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001330 static class CpuBinder extends Binder {
1331 ActivityManagerService mActivityManagerService;
1332 CpuBinder(ActivityManagerService activityManagerService) {
1333 mActivityManagerService = activityManagerService;
1334 }
1335
1336 @Override
1337 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1338 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001339 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1340 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1341 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 }
1343 }
1344 }
1345
1346 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001347 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 File dataDir = Environment.getDataDirectory();
1350 File systemDir = new File(dataDir, "system");
1351 systemDir.mkdirs();
1352 mBatteryStatsService = new BatteryStatsService(new File(
1353 systemDir, "batterystats.bin").toString());
1354 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001355 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001356 mOnBattery = DEBUG_POWER ? true
1357 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001358 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001360 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001361 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362
Jack Palevichb90d28c2009-07-22 15:35:24 -07001363 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1364 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1365
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001366 mConfiguration.setToDefaults();
1367 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 mProcessStats.init();
1369
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001370 mCompatModePackages = new CompatModePackages(this, systemDir);
1371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 // Add ourself to the Watchdog monitors.
1373 Watchdog.getInstance().addMonitor(this);
1374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 mProcessStatsThread = new Thread("ProcessStats") {
1376 public void run() {
1377 while (true) {
1378 try {
1379 try {
1380 synchronized(this) {
1381 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001382 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001384 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001385 // + ", write delay=" + nextWriteDelay);
1386 if (nextWriteDelay < nextCpuDelay) {
1387 nextCpuDelay = nextWriteDelay;
1388 }
1389 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001390 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 this.wait(nextCpuDelay);
1392 }
1393 }
1394 } catch (InterruptedException e) {
1395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001396 updateCpuStatsNow();
1397 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001398 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001399 }
1400 }
1401 }
1402 };
1403 mProcessStatsThread.start();
1404 }
1405
1406 @Override
1407 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1408 throws RemoteException {
1409 try {
1410 return super.onTransact(code, data, reply, flags);
1411 } catch (RuntimeException e) {
1412 // The activity manager only throws security exceptions, so let's
1413 // log all others.
1414 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001415 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 }
1417 throw e;
1418 }
1419 }
1420
1421 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001422 final long now = SystemClock.uptimeMillis();
1423 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1424 return;
1425 }
1426 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1427 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 mProcessStatsThread.notify();
1429 }
1430 }
1431 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 void updateCpuStatsNow() {
1434 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001435 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 final long now = SystemClock.uptimeMillis();
1437 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001440 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1441 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 haveNewCpuStats = true;
1443 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001444 //Slog.i(TAG, mProcessStats.printCurrentState());
1445 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 // + mProcessStats.getTotalCpuPercent() + "%");
1447
Joe Onorato8a9b2202010-02-26 18:56:32 -08001448 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 if ("true".equals(SystemProperties.get("events.cpu"))) {
1450 int user = mProcessStats.getLastUserTime();
1451 int system = mProcessStats.getLastSystemTime();
1452 int iowait = mProcessStats.getLastIoWaitTime();
1453 int irq = mProcessStats.getLastIrqTime();
1454 int softIrq = mProcessStats.getLastSoftIrqTime();
1455 int idle = mProcessStats.getLastIdleTime();
1456
1457 int total = user + system + iowait + irq + softIrq + idle;
1458 if (total == 0) total = 1;
1459
Doug Zongker2bec3d42009-12-04 12:52:44 -08001460 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 ((user+system+iowait+irq+softIrq) * 100) / total,
1462 (user * 100) / total,
1463 (system * 100) / total,
1464 (iowait * 100) / total,
1465 (irq * 100) / total,
1466 (softIrq * 100) / total);
1467 }
1468 }
1469
Amith Yamasanie43530a2009-08-21 13:11:37 -07001470 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001471 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001472 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 synchronized(mPidsSelfLocked) {
1474 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001475 if (mOnBattery) {
1476 int perc = bstats.startAddingCpuLocked();
1477 int totalUTime = 0;
1478 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001479 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001481 ProcessStats.Stats st = mProcessStats.getStats(i);
1482 if (!st.working) {
1483 continue;
1484 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001485 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001486 int otherUTime = (st.rel_utime*perc)/100;
1487 int otherSTime = (st.rel_stime*perc)/100;
1488 totalUTime += otherUTime;
1489 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 if (pr != null) {
1491 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001492 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1493 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001494 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001495 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001496 } else {
1497 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001498 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001499 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001500 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1501 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001502 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 }
1505 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001506 bstats.finishAddingCpuLocked(perc, totalUTime,
1507 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 }
1509 }
1510 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1513 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001514 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 }
1516 }
1517 }
1518 }
1519
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001520 @Override
1521 public void batteryNeedsCpuUpdate() {
1522 updateCpuStatsNow();
1523 }
1524
1525 @Override
1526 public void batteryPowerChanged(boolean onBattery) {
1527 // When plugging in, update the CPU stats first before changing
1528 // the plug state.
1529 updateCpuStatsNow();
1530 synchronized (this) {
1531 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001532 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001533 }
1534 }
1535 }
1536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 /**
1538 * Initialize the application bind args. These are passed to each
1539 * process when the bindApplication() IPC is sent to the process. They're
1540 * lazily setup to make sure the services are running when they're asked for.
1541 */
1542 private HashMap<String, IBinder> getCommonServicesLocked() {
1543 if (mAppBindArgs == null) {
1544 mAppBindArgs = new HashMap<String, IBinder>();
1545
1546 // Setup the application init args
1547 mAppBindArgs.put("package", ServiceManager.getService("package"));
1548 mAppBindArgs.put("window", ServiceManager.getService("window"));
1549 mAppBindArgs.put(Context.ALARM_SERVICE,
1550 ServiceManager.getService(Context.ALARM_SERVICE));
1551 }
1552 return mAppBindArgs;
1553 }
1554
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001555 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 if (mFocusedActivity != r) {
1557 mFocusedActivity = r;
1558 mWindowManager.setFocusedApp(r, true);
1559 }
1560 }
1561
Dianne Hackborn906497c2010-05-10 15:57:38 -07001562 private final void updateLruProcessInternalLocked(ProcessRecord app,
1563 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001565 int lrui = mLruProcesses.indexOf(app);
1566 if (lrui >= 0) mLruProcesses.remove(lrui);
1567
1568 int i = mLruProcesses.size()-1;
1569 int skipTop = 0;
1570
Dianne Hackborn906497c2010-05-10 15:57:38 -07001571 app.lruSeq = mLruSeq;
1572
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001573 // compute the new weight for this process.
1574 if (updateActivityTime) {
1575 app.lastActivityTime = SystemClock.uptimeMillis();
1576 }
1577 if (app.activities.size() > 0) {
1578 // If this process has activities, we more strongly want to keep
1579 // it around.
1580 app.lruWeight = app.lastActivityTime;
1581 } else if (app.pubProviders.size() > 0) {
1582 // If this process contains content providers, we want to keep
1583 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001584 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001585 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001586 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001587 } else {
1588 // If this process doesn't have activities, we less strongly
1589 // want to keep it around, and generally want to avoid getting
1590 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001591 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001592 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001593 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001594 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001595
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001596 while (i >= 0) {
1597 ProcessRecord p = mLruProcesses.get(i);
1598 // If this app shouldn't be in front of the first N background
1599 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001600 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001601 skipTop--;
1602 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001603 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001604 mLruProcesses.add(i+1, app);
1605 break;
1606 }
1607 i--;
1608 }
1609 if (i < 0) {
1610 mLruProcesses.add(0, app);
1611 }
1612
Dianne Hackborn906497c2010-05-10 15:57:38 -07001613 // If the app is currently using a content provider or service,
1614 // bump those processes as well.
1615 if (app.connections.size() > 0) {
1616 for (ConnectionRecord cr : app.connections) {
1617 if (cr.binding != null && cr.binding.service != null
1618 && cr.binding.service.app != null
1619 && cr.binding.service.app.lruSeq != mLruSeq) {
1620 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1621 updateActivityTime, i+1);
1622 }
1623 }
1624 }
1625 if (app.conProviders.size() > 0) {
1626 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1627 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1628 updateLruProcessInternalLocked(cpr.app, oomAdj,
1629 updateActivityTime, i+1);
1630 }
1631 }
1632 }
1633
Joe Onorato8a9b2202010-02-26 18:56:32 -08001634 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 if (oomAdj) {
1636 updateOomAdjLocked();
1637 }
1638 }
1639
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001640 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001641 boolean oomAdj, boolean updateActivityTime) {
1642 mLruSeq++;
1643 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1644 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001645
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001646 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001647 String processName, int uid) {
1648 if (uid == Process.SYSTEM_UID) {
1649 // The system gets to run in any process. If there are multiple
1650 // processes with the same uid, just pick the first (this
1651 // should never happen).
1652 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1653 processName);
1654 return procs != null ? procs.valueAt(0) : null;
1655 }
1656 ProcessRecord proc = mProcessNames.get(processName, uid);
1657 return proc;
1658 }
1659
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001660 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001661 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001662 try {
1663 if (pm.performDexOpt(packageName)) {
1664 mDidDexOpt = true;
1665 }
1666 } catch (RemoteException e) {
1667 }
1668 }
1669
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001670 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001671 int transit = mWindowManager.getPendingAppTransition();
1672 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1673 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1674 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1675 }
1676
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001677 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001679 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1681 // We don't have to do anything more if:
1682 // (1) There is an existing application record; and
1683 // (2) The caller doesn't think it is dead, OR there is no thread
1684 // object attached to it so we know it couldn't have crashed; and
1685 // (3) There is a pid assigned to it, so it is either starting or
1686 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001687 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001688 + " app=" + app + " knownToBeDead=" + knownToBeDead
1689 + " thread=" + (app != null ? app.thread : null)
1690 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001691 if (app != null && app.pid > 0) {
1692 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001693 // We already have the app running, or are waiting for it to
1694 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001695 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001696 // If this is a new package in the process, add the package to the list
1697 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001698 return app;
1699 } else {
1700 // An application record is attached to a previous process,
1701 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001702 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001703 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001704 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001705 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001706
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707 String hostingNameStr = hostingName != null
1708 ? hostingName.flattenToShortString() : null;
1709
1710 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1711 // If we are in the background, then check to see if this process
1712 // is bad. If so, we will just silently fail.
1713 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001714 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1715 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001716 return null;
1717 }
1718 } else {
1719 // When the user is explicitly starting a process, then clear its
1720 // crash count so that we won't make it bad until they see at
1721 // least one crash dialog again, and make the process good again
1722 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001723 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1724 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 mProcessCrashTimes.remove(info.processName, info.uid);
1726 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001727 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001728 info.processName);
1729 mBadProcesses.remove(info.processName, info.uid);
1730 if (app != null) {
1731 app.bad = false;
1732 }
1733 }
1734 }
1735
1736 if (app == null) {
1737 app = newProcessRecordLocked(null, info, processName);
1738 mProcessNames.put(processName, info.uid, app);
1739 } else {
1740 // If this is a new package in the process, add the package to the list
1741 app.addPackage(info.packageName);
1742 }
1743
1744 // If the system is not ready yet, then hold off on starting this
1745 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001746 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001747 && !isAllowedWhileBooting(info)
1748 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 if (!mProcessesOnHold.contains(app)) {
1750 mProcessesOnHold.add(app);
1751 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001752 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 return app;
1754 }
1755
1756 startProcessLocked(app, hostingType, hostingNameStr);
1757 return (app.pid != 0) ? app : null;
1758 }
1759
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001760 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1761 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1762 }
1763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001764 private final void startProcessLocked(ProcessRecord app,
1765 String hostingType, String hostingNameStr) {
1766 if (app.pid > 0 && app.pid != MY_PID) {
1767 synchronized (mPidsSelfLocked) {
1768 mPidsSelfLocked.remove(app.pid);
1769 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1770 }
1771 app.pid = 0;
1772 }
1773
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001774 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1775 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001776 mProcessesOnHold.remove(app);
1777
1778 updateCpuStats();
1779
1780 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1781 mProcDeaths[0] = 0;
1782
1783 try {
1784 int uid = app.info.uid;
1785 int[] gids = null;
1786 try {
1787 gids = mContext.getPackageManager().getPackageGids(
1788 app.info.packageName);
1789 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001790 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 }
1792 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1793 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1794 && mTopComponent != null
1795 && app.processName.equals(mTopComponent.getPackageName())) {
1796 uid = 0;
1797 }
1798 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1799 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1800 uid = 0;
1801 }
1802 }
1803 int debugFlags = 0;
1804 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1805 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001806 // Also turn on CheckJNI for debuggable apps. It's quite
1807 // awkward to turn on otherwise.
1808 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001810 // Run the app in safe mode if its manifest requests so or the
1811 // system is booted in safe mode.
1812 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1813 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001814 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1815 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1817 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1818 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001819 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1820 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 if ("1".equals(SystemProperties.get("debug.assert"))) {
1823 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1824 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001825
1826 // Start the process. It will either succeed and return a result containing
1827 // the PID of the new process, or else throw a RuntimeException.
1828 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001829 app.processName, uid, uid, gids, debugFlags,
1830 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1833 synchronized (bs) {
1834 if (bs.isOnBattery()) {
1835 app.batteryStats.incStartsLocked();
1836 }
1837 }
1838
Jeff Brown3f9dd282011-07-08 20:02:19 -07001839 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 app.processName, hostingType,
1841 hostingNameStr != null ? hostingNameStr : "");
1842
1843 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001844 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001845 }
1846
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001847 StringBuilder buf = mStringBuilder;
1848 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 buf.append("Start proc ");
1850 buf.append(app.processName);
1851 buf.append(" for ");
1852 buf.append(hostingType);
1853 if (hostingNameStr != null) {
1854 buf.append(" ");
1855 buf.append(hostingNameStr);
1856 }
1857 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001858 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001859 buf.append(" uid=");
1860 buf.append(uid);
1861 buf.append(" gids={");
1862 if (gids != null) {
1863 for (int gi=0; gi<gids.length; gi++) {
1864 if (gi != 0) buf.append(", ");
1865 buf.append(gids[gi]);
1866
1867 }
1868 }
1869 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001870 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001871 app.pid = startResult.pid;
1872 app.usingWrapper = startResult.usingWrapper;
1873 app.removed = false;
1874 synchronized (mPidsSelfLocked) {
1875 this.mPidsSelfLocked.put(startResult.pid, app);
1876 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1877 msg.obj = app;
1878 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1879 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 }
1881 } catch (RuntimeException e) {
1882 // XXX do better error recovery.
1883 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001884 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885 }
1886 }
1887
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001888 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001889 if (resumed) {
1890 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1891 } else {
1892 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1893 }
1894 }
1895
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001896 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001897 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1898 && mTopAction == null) {
1899 // We are running in factory test mode, but unable to find
1900 // the factory test app, so just sit around displaying the
1901 // error message and don't try to start anything.
1902 return false;
1903 }
1904 Intent intent = new Intent(
1905 mTopAction,
1906 mTopData != null ? Uri.parse(mTopData) : null);
1907 intent.setComponent(mTopComponent);
1908 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1909 intent.addCategory(Intent.CATEGORY_HOME);
1910 }
1911 ActivityInfo aInfo =
1912 intent.resolveActivityInfo(mContext.getPackageManager(),
1913 STOCK_PM_FLAGS);
1914 if (aInfo != null) {
1915 intent.setComponent(new ComponentName(
1916 aInfo.applicationInfo.packageName, aInfo.name));
1917 // Don't do this if the home app is currently being
1918 // instrumented.
1919 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1920 aInfo.applicationInfo.uid);
1921 if (app == null || app.instrumentationClass == null) {
1922 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001923 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001924 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001925 }
1926 }
1927
1928
1929 return true;
1930 }
1931
1932 /**
1933 * Starts the "new version setup screen" if appropriate.
1934 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001935 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001936 // Only do this once per boot.
1937 if (mCheckedForSetup) {
1938 return;
1939 }
1940
1941 // We will show this screen if the current one is a different
1942 // version than the last one shown, and we are not running in
1943 // low-level factory test mode.
1944 final ContentResolver resolver = mContext.getContentResolver();
1945 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1946 Settings.Secure.getInt(resolver,
1947 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1948 mCheckedForSetup = true;
1949
1950 // See if we should be showing the platform update setup UI.
1951 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1952 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1953 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1954
1955 // We don't allow third party apps to replace this.
1956 ResolveInfo ri = null;
1957 for (int i=0; ris != null && i<ris.size(); i++) {
1958 if ((ris.get(i).activityInfo.applicationInfo.flags
1959 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1960 ri = ris.get(i);
1961 break;
1962 }
1963 }
1964
1965 if (ri != null) {
1966 String vers = ri.activityInfo.metaData != null
1967 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1968 : null;
1969 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1970 vers = ri.activityInfo.applicationInfo.metaData.getString(
1971 Intent.METADATA_SETUP_VERSION);
1972 }
1973 String lastVers = Settings.Secure.getString(
1974 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1975 if (vers != null && !vers.equals(lastVers)) {
1976 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1977 intent.setComponent(new ComponentName(
1978 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001979 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001980 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001981 }
1982 }
1983 }
1984 }
1985
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001986 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001987 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001988 }
1989
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001990 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001991 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001992 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
1993 }
1994 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001995
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001996 public void setFrontActivityScreenCompatMode(int mode) {
1997 synchronized (this) {
1998 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
1999 }
2000 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002001
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002002 public int getPackageScreenCompatMode(String packageName) {
2003 synchronized (this) {
2004 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2005 }
2006 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002007
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002008 public void setPackageScreenCompatMode(String packageName, int mode) {
2009 synchronized (this) {
2010 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002011 }
2012 }
2013
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002014 public boolean getPackageAskScreenCompat(String packageName) {
2015 synchronized (this) {
2016 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2017 }
2018 }
2019
2020 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2021 synchronized (this) {
2022 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2023 }
2024 }
2025
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002026 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002027 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002028
2029 final int identHash = System.identityHashCode(r);
2030 updateUsageStats(r, true);
2031
2032 int i = mWatchers.beginBroadcast();
2033 while (i > 0) {
2034 i--;
2035 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2036 if (w != null) {
2037 try {
2038 w.activityResuming(identHash);
2039 } catch (RemoteException e) {
2040 }
2041 }
2042 }
2043 mWatchers.finishBroadcast();
2044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002045
Jeff Sharkeya4620792011-05-20 15:29:23 -07002046 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2047 int i = mProcessObservers.beginBroadcast();
2048 while (i > 0) {
2049 i--;
2050 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2051 if (observer != null) {
2052 try {
2053 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2054 } catch (RemoteException e) {
2055 }
2056 }
2057 }
2058 mProcessObservers.finishBroadcast();
2059 }
2060
2061 private void dispatchProcessDied(int pid, int uid) {
2062 int i = mProcessObservers.beginBroadcast();
2063 while (i > 0) {
2064 i--;
2065 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2066 if (observer != null) {
2067 try {
2068 observer.onProcessDied(pid, uid);
2069 } catch (RemoteException e) {
2070 }
2071 }
2072 }
2073 mProcessObservers.finishBroadcast();
2074 }
2075
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002076 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002077 final int N = mPendingActivityLaunches.size();
2078 if (N <= 0) {
2079 return;
2080 }
2081 for (int i=0; i<N; i++) {
2082 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002083 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002084 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2085 doResume && i == (N-1));
2086 }
2087 mPendingActivityLaunches.clear();
2088 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002089
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002090 public final int startActivity(IApplicationThread caller,
2091 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2092 int grantedMode, IBinder resultTo,
2093 String resultWho, int requestCode, boolean onlyIfNeeded,
2094 boolean debug) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002095 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002096 grantedUriPermissions, grantedMode, resultTo, resultWho,
2097 requestCode, onlyIfNeeded, debug, null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002098 }
2099
2100 public final WaitResult startActivityAndWait(IApplicationThread caller,
2101 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2102 int grantedMode, IBinder resultTo,
2103 String resultWho, int requestCode, boolean onlyIfNeeded,
2104 boolean debug) {
2105 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002106 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002107 grantedUriPermissions, grantedMode, resultTo, resultWho,
2108 requestCode, onlyIfNeeded, debug, res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002109 return res;
2110 }
2111
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002112 public final int startActivityWithConfig(IApplicationThread caller,
2113 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2114 int grantedMode, IBinder resultTo,
2115 String resultWho, int requestCode, boolean onlyIfNeeded,
2116 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002117 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002118 grantedUriPermissions, grantedMode, resultTo, resultWho,
2119 requestCode, onlyIfNeeded, debug, null, config);
2120 }
2121
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002122 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002123 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002124 IBinder resultTo, String resultWho, int requestCode,
2125 int flagsMask, int flagsValues) {
2126 // Refuse possible leaked file descriptors
2127 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2128 throw new IllegalArgumentException("File descriptors passed in Intent");
2129 }
2130
2131 IIntentSender sender = intent.getTarget();
2132 if (!(sender instanceof PendingIntentRecord)) {
2133 throw new IllegalArgumentException("Bad PendingIntent object");
2134 }
2135
2136 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002137
2138 synchronized (this) {
2139 // If this is coming from the currently resumed activity, it is
2140 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002141 if (mMainStack.mResumedActivity != null
2142 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002143 Binder.getCallingUid()) {
2144 mAppSwitchesAllowedTime = 0;
2145 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002146 }
2147
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002148 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002149 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2150 }
2151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002152 public boolean startNextMatchingActivity(IBinder callingActivity,
2153 Intent intent) {
2154 // Refuse possible leaked file descriptors
2155 if (intent != null && intent.hasFileDescriptors() == true) {
2156 throw new IllegalArgumentException("File descriptors passed in Intent");
2157 }
2158
2159 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002160 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2161 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 return false;
2163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 if (r.app == null || r.app.thread == null) {
2165 // The caller is not running... d'oh!
2166 return false;
2167 }
2168 intent = new Intent(intent);
2169 // The caller is not allowed to change the data.
2170 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2171 // And we are resetting to find the next component...
2172 intent.setComponent(null);
2173
2174 ActivityInfo aInfo = null;
2175 try {
2176 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002177 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002179 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002180
2181 // Look for the original activity in the list...
2182 final int N = resolves != null ? resolves.size() : 0;
2183 for (int i=0; i<N; i++) {
2184 ResolveInfo rInfo = resolves.get(i);
2185 if (rInfo.activityInfo.packageName.equals(r.packageName)
2186 && rInfo.activityInfo.name.equals(r.info.name)) {
2187 // We found the current one... the next matching is
2188 // after it.
2189 i++;
2190 if (i<N) {
2191 aInfo = resolves.get(i).activityInfo;
2192 }
2193 break;
2194 }
2195 }
2196 } catch (RemoteException e) {
2197 }
2198
2199 if (aInfo == null) {
2200 // Nobody who is next!
2201 return false;
2202 }
2203
2204 intent.setComponent(new ComponentName(
2205 aInfo.applicationInfo.packageName, aInfo.name));
2206 intent.setFlags(intent.getFlags()&~(
2207 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2208 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2209 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2210 Intent.FLAG_ACTIVITY_NEW_TASK));
2211
2212 // Okay now we need to start the new activity, replacing the
2213 // currently running activity. This is a little tricky because
2214 // we want to start the new one as if the current one is finished,
2215 // but not finish the current one first so that there is no flicker.
2216 // And thus...
2217 final boolean wasFinishing = r.finishing;
2218 r.finishing = true;
2219
2220 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002221 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002222 final String resultWho = r.resultWho;
2223 final int requestCode = r.requestCode;
2224 r.resultTo = null;
2225 if (resultTo != null) {
2226 resultTo.removeResultsLocked(r, resultWho, requestCode);
2227 }
2228
2229 final long origId = Binder.clearCallingIdentity();
2230 // XXX we are not dealing with propagating grantedUriPermissions...
2231 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002232 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002233 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002234 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002235 Binder.restoreCallingIdentity(origId);
2236
2237 r.finishing = wasFinishing;
2238 if (res != START_SUCCESS) {
2239 return false;
2240 }
2241 return true;
2242 }
2243 }
2244
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002245 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002246 Intent intent, String resolvedType, IBinder resultTo,
2247 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002248
2249 // This is so super not safe, that only the system (or okay root)
2250 // can do it.
2251 final int callingUid = Binder.getCallingUid();
2252 if (callingUid != 0 && callingUid != Process.myUid()) {
2253 throw new SecurityException(
2254 "startActivityInPackage only available to the system");
2255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002257 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
2258 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false, null, null);
2259 }
2260
2261 public final int startActivities(IApplicationThread caller,
2262 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2263 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2264 }
2265
2266 public final int startActivitiesInPackage(int uid,
2267 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2268
2269 // This is so super not safe, that only the system (or okay root)
2270 // can do it.
2271 final int callingUid = Binder.getCallingUid();
2272 if (callingUid != 0 && callingUid != Process.myUid()) {
2273 throw new SecurityException(
2274 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 }
2276
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002277 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002278 }
2279
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002280 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002282 // Quick case: check if the top-most recent task is the same.
2283 if (N > 0 && mRecentTasks.get(0) == task) {
2284 return;
2285 }
2286 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 for (int i=0; i<N; i++) {
2288 TaskRecord tr = mRecentTasks.get(i);
2289 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2290 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2291 mRecentTasks.remove(i);
2292 i--;
2293 N--;
2294 if (task.intent == null) {
2295 // If the new recent task we are adding is not fully
2296 // specified, then replace it with the existing recent task.
2297 task = tr;
2298 }
2299 }
2300 }
2301 if (N >= MAX_RECENT_TASKS) {
2302 mRecentTasks.remove(N-1);
2303 }
2304 mRecentTasks.add(0, task);
2305 }
2306
2307 public void setRequestedOrientation(IBinder token,
2308 int requestedOrientation) {
2309 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002310 ActivityRecord r = mMainStack.isInStackLocked(token);
2311 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 return;
2313 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314 final long origId = Binder.clearCallingIdentity();
2315 mWindowManager.setAppOrientation(r, requestedOrientation);
2316 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002317 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318 r.mayFreezeScreenLocked(r.app) ? r : null);
2319 if (config != null) {
2320 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002321 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002322 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 }
2324 }
2325 Binder.restoreCallingIdentity(origId);
2326 }
2327 }
2328
2329 public int getRequestedOrientation(IBinder token) {
2330 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002331 ActivityRecord r = mMainStack.isInStackLocked(token);
2332 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 return mWindowManager.getAppOrientation(r);
2336 }
2337 }
2338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002339 /**
2340 * This is the internal entry point for handling Activity.finish().
2341 *
2342 * @param token The Binder token referencing the Activity we want to finish.
2343 * @param resultCode Result code, if any, from this Activity.
2344 * @param resultData Result data (Intent), if any, from this Activity.
2345 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002346 * @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 -08002347 */
2348 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2349 // Refuse possible leaked file descriptors
2350 if (resultData != null && resultData.hasFileDescriptors() == true) {
2351 throw new IllegalArgumentException("File descriptors passed in Intent");
2352 }
2353
2354 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002355 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002357 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 if (next != null) {
2359 // ask watcher if this is allowed
2360 boolean resumeOK = true;
2361 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002362 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002364 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365 }
2366
2367 if (!resumeOK) {
2368 return false;
2369 }
2370 }
2371 }
2372 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002373 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 resultData, "app-request");
2375 Binder.restoreCallingIdentity(origId);
2376 return res;
2377 }
2378 }
2379
Dianne Hackborn860755f2010-06-03 18:47:52 -07002380 public final void finishHeavyWeightApp() {
2381 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2382 != PackageManager.PERMISSION_GRANTED) {
2383 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2384 + Binder.getCallingPid()
2385 + ", uid=" + Binder.getCallingUid()
2386 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2387 Slog.w(TAG, msg);
2388 throw new SecurityException(msg);
2389 }
2390
2391 synchronized(this) {
2392 if (mHeavyWeightProcess == null) {
2393 return;
2394 }
2395
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002396 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002397 mHeavyWeightProcess.activities);
2398 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002399 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002400 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002401 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002402 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002403 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002404 null, "finish-heavy");
2405 }
2406 }
2407 }
2408
2409 mHeavyWeightProcess = null;
2410 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2411 }
2412 }
2413
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002414 public void crashApplication(int uid, int initialPid, String packageName,
2415 String message) {
2416 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2417 != PackageManager.PERMISSION_GRANTED) {
2418 String msg = "Permission Denial: crashApplication() from pid="
2419 + Binder.getCallingPid()
2420 + ", uid=" + Binder.getCallingUid()
2421 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2422 Slog.w(TAG, msg);
2423 throw new SecurityException(msg);
2424 }
2425
2426 synchronized(this) {
2427 ProcessRecord proc = null;
2428
2429 // Figure out which process to kill. We don't trust that initialPid
2430 // still has any relation to current pids, so must scan through the
2431 // list.
2432 synchronized (mPidsSelfLocked) {
2433 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2434 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2435 if (p.info.uid != uid) {
2436 continue;
2437 }
2438 if (p.pid == initialPid) {
2439 proc = p;
2440 break;
2441 }
2442 for (String str : p.pkgList) {
2443 if (str.equals(packageName)) {
2444 proc = p;
2445 }
2446 }
2447 }
2448 }
2449
2450 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002451 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002452 + " initialPid=" + initialPid
2453 + " packageName=" + packageName);
2454 return;
2455 }
2456
2457 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002458 if (proc.pid == Process.myPid()) {
2459 Log.w(TAG, "crashApplication: trying to crash self!");
2460 return;
2461 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002462 long ident = Binder.clearCallingIdentity();
2463 try {
2464 proc.thread.scheduleCrash(message);
2465 } catch (RemoteException e) {
2466 }
2467 Binder.restoreCallingIdentity(ident);
2468 }
2469 }
2470 }
2471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 public final void finishSubActivity(IBinder token, String resultWho,
2473 int requestCode) {
2474 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002475 ActivityRecord self = mMainStack.isInStackLocked(token);
2476 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 return;
2478 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002479
2480 final long origId = Binder.clearCallingIdentity();
2481
2482 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002483 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2484 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 if (r.resultTo == self && r.requestCode == requestCode) {
2486 if ((r.resultWho == null && resultWho == null) ||
2487 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002488 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002489 Activity.RESULT_CANCELED, null, "request-sub");
2490 }
2491 }
2492 }
2493
2494 Binder.restoreCallingIdentity(origId);
2495 }
2496 }
2497
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002498 public boolean willActivityBeVisible(IBinder token) {
2499 synchronized(this) {
2500 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002501 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2502 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002503 if (r == token) {
2504 return true;
2505 }
2506 if (r.fullscreen && !r.finishing) {
2507 return false;
2508 }
2509 }
2510 return true;
2511 }
2512 }
2513
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002514 public void overridePendingTransition(IBinder token, String packageName,
2515 int enterAnim, int exitAnim) {
2516 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002517 ActivityRecord self = mMainStack.isInStackLocked(token);
2518 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002519 return;
2520 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002521
2522 final long origId = Binder.clearCallingIdentity();
2523
2524 if (self.state == ActivityState.RESUMED
2525 || self.state == ActivityState.PAUSING) {
2526 mWindowManager.overridePendingAppTransition(packageName,
2527 enterAnim, exitAnim);
2528 }
2529
2530 Binder.restoreCallingIdentity(origId);
2531 }
2532 }
2533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002535 * Main function for removing an existing process from the activity manager
2536 * as a result of that process going away. Clears out all connections
2537 * to the process.
2538 */
2539 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002540 boolean restarting, boolean allowRestart) {
2541 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002543 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 }
2545
2546 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002547 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2548 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2549 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002550 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002551 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2552 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 }
2554
2555 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002556 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002557
2558 boolean atTop = true;
2559 boolean hasVisibleActivities = false;
2560
2561 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002562 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002563 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 TAG, "Removing app " + app + " from history with " + i + " entries");
2565 while (i > 0) {
2566 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002567 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002568 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2570 if (r.app == app) {
2571 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002572 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002573 TAG, "Removing this entry! frozen=" + r.haveState
2574 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002575 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002576 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002577 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002578 mWindowManager.removeAppToken(r);
2579 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002580 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002582 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583
2584 } else {
2585 // We have the current state for this activity, so
2586 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002587 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002588 TAG, "Keeping entry, setting app to null");
2589 if (r.visible) {
2590 hasVisibleActivities = true;
2591 }
2592 r.app = null;
2593 r.nowVisible = false;
2594 if (!r.haveState) {
2595 r.icicle = null;
2596 }
2597 }
2598
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002599 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002600 }
2601 atTop = false;
2602 }
2603
2604 app.activities.clear();
2605
2606 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002607 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 + " running instrumentation " + app.instrumentationClass);
2609 Bundle info = new Bundle();
2610 info.putString("shortMsg", "Process crashed.");
2611 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2612 }
2613
2614 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002615 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002616 // If there was nothing to resume, and we are not already
2617 // restarting this process, but there is a visible activity that
2618 // is hosted by the process... then make sure all visible
2619 // activities are running, taking care of restarting this
2620 // process.
2621 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002622 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002623 }
2624 }
2625 }
2626 }
2627
2628 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2629 IBinder threadBinder = thread.asBinder();
2630
2631 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002632 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2633 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002634 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2635 return i;
2636 }
2637 }
2638 return -1;
2639 }
2640
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002641 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002642 IApplicationThread thread) {
2643 if (thread == null) {
2644 return null;
2645 }
2646
2647 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002648 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 }
2650
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002651 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 IApplicationThread thread) {
2653
2654 mProcDeaths[0]++;
2655
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002656 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2657 synchronized (stats) {
2658 stats.noteProcessDiedLocked(app.info.uid, pid);
2659 }
2660
Magnus Edlund7bb25812010-02-24 15:45:06 +01002661 // Clean up already done if the process has been re-started.
2662 if (app.pid == pid && app.thread != null &&
2663 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002664 if (!app.killedBackground) {
2665 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2666 + ") has died.");
2667 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002668 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002669 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 TAG, "Dying app: " + app + ", pid: " + pid
2671 + ", thread: " + thread.asBinder());
2672 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002673 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002674
2675 if (doLowMem) {
2676 // If there are no longer any background processes running,
2677 // and the app that died was not running instrumentation,
2678 // then tell everyone we are now low on memory.
2679 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002680 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2681 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002682 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 haveBg = true;
2684 break;
2685 }
2686 }
2687
2688 if (!haveBg) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002689 Slog.i(TAG, "Low Memory: No more background processes.");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002690 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002691 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002692 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2693 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002694 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002695 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2696 // The low memory report is overriding any current
2697 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002698 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002699 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002700 rec.lastRequestedGc = 0;
2701 } else {
2702 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002703 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002704 rec.reportLowMemory = true;
2705 rec.lastLowMemory = now;
2706 mProcessesToGc.remove(rec);
2707 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 }
2709 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002710 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 }
2712 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002713 } else if (app.pid != pid) {
2714 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002715 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002716 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002717 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002718 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002719 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 + thread.asBinder());
2721 }
2722 }
2723
Dan Egnor42471dd2010-01-07 17:25:22 -08002724 /**
2725 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002726 * @param clearTraces causes the dump file to be erased prior to the new
2727 * traces being written, if true; when false, the new traces will be
2728 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002729 * @param firstPids of dalvik VM processes to dump stack traces for first
2730 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002731 * @return file containing stack traces, or null if no dump file is configured
2732 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002733 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2734 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002735 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2736 if (tracesPath == null || tracesPath.length() == 0) {
2737 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002739
2740 File tracesFile = new File(tracesPath);
2741 try {
2742 File tracesDir = tracesFile.getParentFile();
2743 if (!tracesDir.exists()) tracesFile.mkdirs();
2744 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2745
Christopher Tate6ee412d2010-05-28 12:01:56 -07002746 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002747 tracesFile.createNewFile();
2748 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2749 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002750 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002751 return null;
2752 }
2753
2754 // Use a FileObserver to detect when traces finish writing.
2755 // The order of traces is considered important to maintain for legibility.
2756 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2757 public synchronized void onEvent(int event, String path) { notify(); }
2758 };
2759
2760 try {
2761 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002762
2763 // First collect all of the stacks of the most important pids.
2764 try {
2765 int num = firstPids.size();
2766 for (int i = 0; i < num; i++) {
2767 synchronized (observer) {
2768 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2769 observer.wait(200); // Wait for write-close, give up after 200msec
2770 }
2771 }
2772 } catch (InterruptedException e) {
2773 Log.wtf(TAG, e);
2774 }
2775
2776 // Next measure CPU usage.
2777 if (processStats != null) {
2778 processStats.init();
2779 System.gc();
2780 processStats.update();
2781 try {
2782 synchronized (processStats) {
2783 processStats.wait(500); // measure over 1/2 second.
2784 }
2785 } catch (InterruptedException e) {
2786 }
2787 processStats.update();
2788
2789 // We'll take the stack crawls of just the top apps using CPU.
2790 final int N = processStats.countWorkingStats();
2791 int numProcs = 0;
2792 for (int i=0; i<N && numProcs<5; i++) {
2793 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2794 if (lastPids.indexOfKey(stats.pid) >= 0) {
2795 numProcs++;
2796 try {
2797 synchronized (observer) {
2798 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2799 observer.wait(200); // Wait for write-close, give up after 200msec
2800 }
2801 } catch (InterruptedException e) {
2802 Log.wtf(TAG, e);
2803 }
2804
2805 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002806 }
2807 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002808
2809 return tracesFile;
2810
Dan Egnor42471dd2010-01-07 17:25:22 -08002811 } finally {
2812 observer.stopWatching();
2813 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 }
2815
Jeff Brown4d94a762010-09-23 11:33:28 -07002816 private final class AppNotResponding implements Runnable {
2817 private final ProcessRecord mApp;
2818 private final String mAnnotation;
2819
2820 public AppNotResponding(ProcessRecord app, String annotation) {
2821 mApp = app;
2822 mAnnotation = annotation;
2823 }
2824
2825 @Override
2826 public void run() {
2827 appNotResponding(mApp, null, null, mAnnotation);
2828 }
2829 }
2830
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002831 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2832 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002833 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2834 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2835
Dianne Hackborn287952c2010-09-22 22:34:31 -07002836 if (mController != null) {
2837 try {
2838 // 0 == continue, -1 = kill process immediately
2839 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2840 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2841 } catch (RemoteException e) {
2842 mController = null;
2843 }
2844 }
2845
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002846 long anrTime = SystemClock.uptimeMillis();
2847 if (MONITOR_CPU_USAGE) {
2848 updateCpuStatsNow();
2849 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002850
2851 synchronized (this) {
2852 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2853 if (mShuttingDown) {
2854 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2855 return;
2856 } else if (app.notResponding) {
2857 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2858 return;
2859 } else if (app.crashing) {
2860 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2861 return;
2862 }
2863
2864 // In case we come through here for the same app before completing
2865 // this one, mark as anring now so we will bail out.
2866 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002867
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002868 // Log the ANR to the event log.
2869 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2870 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002871
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002872 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002873 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002874
2875 int parentPid = app.pid;
2876 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002877 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002878
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002879 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002880
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002881 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2882 ProcessRecord r = mLruProcesses.get(i);
2883 if (r != null && r.thread != null) {
2884 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002885 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2886 if (r.persistent) {
2887 firstPids.add(pid);
2888 } else {
2889 lastPids.put(pid, Boolean.TRUE);
2890 }
2891 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 }
2894 }
2895
Dan Egnor42471dd2010-01-07 17:25:22 -08002896 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002897 StringBuilder info = mStringBuilder;
2898 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002899 info.append("ANR in ").append(app.processName);
2900 if (activity != null && activity.shortComponentName != null) {
2901 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002902 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002903 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002904 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002905 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002907 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002908 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910
Dianne Hackborn287952c2010-09-22 22:34:31 -07002911 final ProcessStats processStats = new ProcessStats(true);
2912
2913 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2914
Dan Egnor42471dd2010-01-07 17:25:22 -08002915 String cpuInfo = null;
2916 if (MONITOR_CPU_USAGE) {
2917 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002918 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002919 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002920 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002921 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002922 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 }
2924
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002925 info.append(processStats.printCurrentState(anrTime));
2926
Joe Onorato8a9b2202010-02-26 18:56:32 -08002927 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002928 if (tracesFile == null) {
2929 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2930 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2931 }
2932
2933 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2934
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002935 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002937 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2938 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002939 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002940 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2941 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002942 }
2943 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002944 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002945 }
2946 }
2947
Dan Egnor42471dd2010-01-07 17:25:22 -08002948 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2949 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2950 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002951
2952 synchronized (this) {
2953 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002954 Slog.w(TAG, "Killing " + app + ": background ANR");
2955 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2956 app.processName, app.setAdj, "background ANR");
2957 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002958 return;
2959 }
2960
2961 // Set the app's notResponding state, and look up the errorReportReceiver
2962 makeAppNotRespondingLocked(app,
2963 activity != null ? activity.shortComponentName : null,
2964 annotation != null ? "ANR " + annotation : "ANR",
2965 info.toString());
2966
2967 // Bring up the infamous App Not Responding dialog
2968 Message msg = Message.obtain();
2969 HashMap map = new HashMap();
2970 msg.what = SHOW_NOT_RESPONDING_MSG;
2971 msg.obj = map;
2972 map.put("app", app);
2973 if (activity != null) {
2974 map.put("activity", activity);
2975 }
2976
2977 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002979 }
2980
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002981 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2982 if (!mLaunchWarningShown) {
2983 mLaunchWarningShown = true;
2984 mHandler.post(new Runnable() {
2985 @Override
2986 public void run() {
2987 synchronized (ActivityManagerService.this) {
2988 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
2989 d.show();
2990 mHandler.postDelayed(new Runnable() {
2991 @Override
2992 public void run() {
2993 synchronized (ActivityManagerService.this) {
2994 d.dismiss();
2995 mLaunchWarningShown = false;
2996 }
2997 }
2998 }, 4000);
2999 }
3000 }
3001 });
3002 }
3003 }
3004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 public boolean clearApplicationUserData(final String packageName,
3006 final IPackageDataObserver observer) {
3007 int uid = Binder.getCallingUid();
3008 int pid = Binder.getCallingPid();
3009 long callingId = Binder.clearCallingIdentity();
3010 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003011 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003012 int pkgUid = -1;
3013 synchronized(this) {
3014 try {
3015 pkgUid = pm.getPackageUid(packageName);
3016 } catch (RemoteException e) {
3017 }
3018 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003019 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003020 return false;
3021 }
3022 if (uid == pkgUid || checkComponentPermission(
3023 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003024 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003026 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003027 } else {
3028 throw new SecurityException(pid+" does not have permission:"+
3029 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3030 "for process:"+packageName);
3031 }
3032 }
3033
3034 try {
3035 //clear application user data
3036 pm.clearApplicationUserData(packageName, observer);
3037 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3038 Uri.fromParts("package", packageName, null));
3039 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003040 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3041 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 } catch (RemoteException e) {
3043 }
3044 } finally {
3045 Binder.restoreCallingIdentity(callingId);
3046 }
3047 return true;
3048 }
3049
Dianne Hackborn03abb812010-01-04 18:43:19 -08003050 public void killBackgroundProcesses(final String packageName) {
3051 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3052 != PackageManager.PERMISSION_GRANTED &&
3053 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3054 != PackageManager.PERMISSION_GRANTED) {
3055 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003056 + Binder.getCallingPid()
3057 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003058 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003059 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003060 throw new SecurityException(msg);
3061 }
3062
3063 long callingId = Binder.clearCallingIdentity();
3064 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003065 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003066 int pkgUid = -1;
3067 synchronized(this) {
3068 try {
3069 pkgUid = pm.getPackageUid(packageName);
3070 } catch (RemoteException e) {
3071 }
3072 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003073 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 return;
3075 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003076 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborn7d608422011-08-07 16:24:18 -07003077 ProcessList.SECONDARY_SERVER_ADJ, false, true, true);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003078 }
3079 } finally {
3080 Binder.restoreCallingIdentity(callingId);
3081 }
3082 }
3083
3084 public void forceStopPackage(final String packageName) {
3085 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3086 != PackageManager.PERMISSION_GRANTED) {
3087 String msg = "Permission Denial: forceStopPackage() from pid="
3088 + Binder.getCallingPid()
3089 + ", uid=" + Binder.getCallingUid()
3090 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003091 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003092 throw new SecurityException(msg);
3093 }
3094
3095 long callingId = Binder.clearCallingIdentity();
3096 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003097 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003098 int pkgUid = -1;
3099 synchronized(this) {
3100 try {
3101 pkgUid = pm.getPackageUid(packageName);
3102 } catch (RemoteException e) {
3103 }
3104 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003105 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003106 return;
3107 }
3108 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003109 try {
3110 pm.setPackageStoppedState(packageName, true);
3111 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003112 } catch (IllegalArgumentException e) {
3113 Slog.w(TAG, "Failed trying to unstop package "
3114 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003115 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003116 }
3117 } finally {
3118 Binder.restoreCallingIdentity(callingId);
3119 }
3120 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003121
3122 /*
3123 * The pkg name and uid have to be specified.
3124 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3125 */
3126 public void killApplicationWithUid(String pkg, int uid) {
3127 if (pkg == null) {
3128 return;
3129 }
3130 // Make sure the uid is valid.
3131 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003132 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003133 return;
3134 }
3135 int callerUid = Binder.getCallingUid();
3136 // Only the system server can kill an application
3137 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003138 // Post an aysnc message to kill the application
3139 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3140 msg.arg1 = uid;
3141 msg.arg2 = 0;
3142 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003143 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003144 } else {
3145 throw new SecurityException(callerUid + " cannot kill pkg: " +
3146 pkg);
3147 }
3148 }
3149
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003150 public void closeSystemDialogs(String reason) {
3151 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003152 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003153 if (reason != null) {
3154 intent.putExtra("reason", reason);
3155 }
3156
3157 final int uid = Binder.getCallingUid();
3158 final long origId = Binder.clearCallingIdentity();
3159 synchronized (this) {
3160 int i = mWatchers.beginBroadcast();
3161 while (i > 0) {
3162 i--;
3163 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3164 if (w != null) {
3165 try {
3166 w.closingSystemDialogs(reason);
3167 } catch (RemoteException e) {
3168 }
3169 }
3170 }
3171 mWatchers.finishBroadcast();
3172
Dianne Hackbornffa42482009-09-23 22:20:11 -07003173 mWindowManager.closeSystemDialogs(reason);
3174
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003175 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3176 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003177 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003178 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003179 Activity.RESULT_CANCELED, null, "close-sys");
3180 }
3181 }
3182
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003183 broadcastIntentLocked(null, null, intent, null,
3184 null, 0, null, null, null, false, false, -1, uid);
3185 }
3186 Binder.restoreCallingIdentity(origId);
3187 }
3188
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003189 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003190 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003191 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3192 for (int i=pids.length-1; i>=0; i--) {
3193 infos[i] = new Debug.MemoryInfo();
3194 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003195 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003196 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003197 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003198
Dianne Hackbornb437e092011-08-05 17:50:29 -07003199 public long[] getProcessPss(int[] pids) throws RemoteException {
3200 long[] pss = new long[pids.length];
3201 for (int i=pids.length-1; i>=0; i--) {
3202 pss[i] = Debug.getPss(pids[i]);
3203 }
3204 return pss;
3205 }
3206
Christopher Tate5e1ab332009-09-01 20:32:49 -07003207 public void killApplicationProcess(String processName, int uid) {
3208 if (processName == null) {
3209 return;
3210 }
3211
3212 int callerUid = Binder.getCallingUid();
3213 // Only the system server can kill an application
3214 if (callerUid == Process.SYSTEM_UID) {
3215 synchronized (this) {
3216 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003217 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003218 try {
3219 app.thread.scheduleSuicide();
3220 } catch (RemoteException e) {
3221 // If the other end already died, then our work here is done.
3222 }
3223 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003224 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003225 + processName + " / " + uid);
3226 }
3227 }
3228 } else {
3229 throw new SecurityException(callerUid + " cannot kill app process: " +
3230 processName);
3231 }
3232 }
3233
Dianne Hackborn03abb812010-01-04 18:43:19 -08003234 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003235 forceStopPackageLocked(packageName, uid, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003236 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3237 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003238 if (!mProcessesReady) {
3239 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3240 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003241 intent.putExtra(Intent.EXTRA_UID, uid);
3242 broadcastIntentLocked(null, null, intent,
3243 null, null, 0, null, null, null,
3244 false, false, MY_PID, Process.SYSTEM_UID);
3245 }
3246
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003247 private final boolean killPackageProcessesLocked(String packageName, int uid,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003248 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003249 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003250
Dianne Hackborn03abb812010-01-04 18:43:19 -08003251 // Remove all processes this package may have touched: all with the
3252 // same UID (except for the system or root user), and all whose name
3253 // matches the package name.
3254 final String procNamePrefix = packageName + ":";
3255 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3256 final int NA = apps.size();
3257 for (int ia=0; ia<NA; ia++) {
3258 ProcessRecord app = apps.valueAt(ia);
Christopher Tate064d8422011-07-26 15:38:07 -07003259 if (app.persistent) {
3260 // we don't kill persistent processes
3261 continue;
3262 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003263 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003264 if (doit) {
3265 procs.add(app);
3266 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003267 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3268 || app.processName.equals(packageName)
3269 || app.processName.startsWith(procNamePrefix)) {
3270 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003271 if (!doit) {
3272 return true;
3273 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003274 app.removed = true;
3275 procs.add(app);
3276 }
3277 }
3278 }
3279 }
3280
3281 int N = procs.size();
3282 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003283 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003284 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003285 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003286 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003287
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003288 private final boolean forceStopPackageLocked(String name, int uid,
3289 boolean callerWillRestart, boolean purgeCache, boolean doit) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003290 int i;
3291 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003292
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003293 if (uid < 0) {
3294 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003295 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003296 } catch (RemoteException e) {
3297 }
3298 }
3299
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003300 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003301 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003302
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003303 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3304 while (badApps.hasNext()) {
3305 SparseArray<Long> ba = badApps.next();
3306 if (ba.get(uid) != null) {
3307 badApps.remove();
3308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003309 }
3310 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003311
3312 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003313 callerWillRestart, false, doit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003314
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003315 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3316 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Christopher Tate064d8422011-07-26 15:38:07 -07003317 if (r.packageName.equals(name)
3318 && (r.app == null || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003319 if (!doit) {
3320 return true;
3321 }
3322 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003323 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 if (r.app != null) {
3325 r.app.removed = true;
3326 }
3327 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003328 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329 }
3330 }
3331
3332 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3333 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003334 if (service.packageName.equals(name)
3335 && (service.app == null || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003336 if (!doit) {
3337 return true;
3338 }
3339 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003340 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003341 if (service.app != null) {
3342 service.app.removed = true;
3343 }
3344 service.app = null;
3345 services.add(service);
3346 }
3347 }
3348
3349 N = services.size();
3350 for (i=0; i<N; i++) {
3351 bringDownServiceLocked(services.get(i), true);
3352 }
3353
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003354 if (doit) {
3355 if (purgeCache) {
3356 AttributeCache ac = AttributeCache.instance();
3357 if (ac != null) {
3358 ac.removePackage(name);
3359 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003360 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003361 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003362 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003363
3364 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365 }
3366
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003367 private final boolean removeProcessLocked(ProcessRecord app,
3368 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003369 final String name = app.processName;
3370 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003371 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003372 TAG, "Force removing process " + app + " (" + name
3373 + "/" + uid + ")");
3374
3375 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003376 if (mHeavyWeightProcess == app) {
3377 mHeavyWeightProcess = null;
3378 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3379 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003380 boolean needRestart = false;
3381 if (app.pid > 0 && app.pid != MY_PID) {
3382 int pid = app.pid;
3383 synchronized (mPidsSelfLocked) {
3384 mPidsSelfLocked.remove(pid);
3385 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3386 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003387 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003388 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003389 Process.killProcess(pid);
3390
3391 if (app.persistent) {
3392 if (!callerWillRestart) {
3393 addAppLocked(app.info);
3394 } else {
3395 needRestart = true;
3396 }
3397 }
3398 } else {
3399 mRemovedProcesses.add(app);
3400 }
3401
3402 return needRestart;
3403 }
3404
3405 private final void processStartTimedOutLocked(ProcessRecord app) {
3406 final int pid = app.pid;
3407 boolean gone = false;
3408 synchronized (mPidsSelfLocked) {
3409 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3410 if (knownApp != null && knownApp.thread == null) {
3411 mPidsSelfLocked.remove(pid);
3412 gone = true;
3413 }
3414 }
3415
3416 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003417 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003418 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003419 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003421 if (mHeavyWeightProcess == app) {
3422 mHeavyWeightProcess = null;
3423 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3424 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003425 // Take care of any launching providers waiting for this process.
3426 checkAppInLaunchingProvidersLocked(app, true);
3427 // Take care of any services that are waiting for the process.
3428 for (int i=0; i<mPendingServices.size(); i++) {
3429 ServiceRecord sr = mPendingServices.get(i);
3430 if (app.info.uid == sr.appInfo.uid
3431 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003432 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003433 mPendingServices.remove(i);
3434 i--;
3435 bringDownServiceLocked(sr, true);
3436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003438 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3439 app.processName, app.setAdj, "start timeout");
3440 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003441 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003442 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003443 try {
3444 IBackupManager bm = IBackupManager.Stub.asInterface(
3445 ServiceManager.getService(Context.BACKUP_SERVICE));
3446 bm.agentDisconnected(app.info.packageName);
3447 } catch (RemoteException e) {
3448 // Can't happen; the backup manager is local
3449 }
3450 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003451 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003452 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003453 mPendingBroadcast.state = BroadcastRecord.IDLE;
3454 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003455 mPendingBroadcast = null;
3456 scheduleBroadcastsLocked();
3457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003458 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003459 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003460 }
3461 }
3462
3463 private final boolean attachApplicationLocked(IApplicationThread thread,
3464 int pid) {
3465
3466 // Find the application record that is being attached... either via
3467 // the pid if we are running in multiple processes, or just pull the
3468 // next app record if we are emulating process with anonymous threads.
3469 ProcessRecord app;
3470 if (pid != MY_PID && pid >= 0) {
3471 synchronized (mPidsSelfLocked) {
3472 app = mPidsSelfLocked.get(pid);
3473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 } else {
3475 app = null;
3476 }
3477
3478 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003479 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003480 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003481 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003482 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003483 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003484 } else {
3485 try {
3486 thread.scheduleExit();
3487 } catch (Exception e) {
3488 // Ignore exceptions.
3489 }
3490 }
3491 return false;
3492 }
3493
3494 // If this application record is still attached to a previous
3495 // process, clean it up now.
3496 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003497 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 }
3499
3500 // Tell the process all about itself.
3501
Joe Onorato8a9b2202010-02-26 18:56:32 -08003502 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003503 TAG, "Binding process pid " + pid + " to record " + app);
3504
3505 String processName = app.processName;
3506 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003507 AppDeathRecipient adr = new AppDeathRecipient(
3508 app, pid, thread);
3509 thread.asBinder().linkToDeath(adr, 0);
3510 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003511 } catch (RemoteException e) {
3512 app.resetPackageList();
3513 startProcessLocked(app, "link fail", processName);
3514 return false;
3515 }
3516
Doug Zongker2bec3d42009-12-04 12:52:44 -08003517 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518
3519 app.thread = thread;
3520 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003521 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3522 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003523 app.forcingToForeground = null;
3524 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003525 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 app.debugging = false;
3527
3528 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3529
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003530 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003531 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003533 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003534 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003535 }
3536
Joe Onorato8a9b2202010-02-26 18:56:32 -08003537 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 TAG, "New app record " + app
3539 + " thread=" + thread.asBinder() + " pid=" + pid);
3540 try {
3541 int testMode = IApplicationThread.DEBUG_OFF;
3542 if (mDebugApp != null && mDebugApp.equals(processName)) {
3543 testMode = mWaitForDebugger
3544 ? IApplicationThread.DEBUG_WAIT
3545 : IApplicationThread.DEBUG_ON;
3546 app.debugging = true;
3547 if (mDebugTransient) {
3548 mDebugApp = mOrigDebugApp;
3549 mWaitForDebugger = mOrigWaitForDebugger;
3550 }
3551 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003552
Christopher Tate181fafa2009-05-14 11:12:14 -07003553 // If the app is being launched for restore or full backup, set it up specially
3554 boolean isRestrictedBackupMode = false;
3555 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3556 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003557 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003558 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3559 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003560
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003561 ensurePackageDexOpt(app.instrumentationInfo != null
3562 ? app.instrumentationInfo.packageName
3563 : app.info.packageName);
3564 if (app.instrumentationClass != null) {
3565 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003566 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003567 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003568 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003569 ApplicationInfo appInfo = app.instrumentationInfo != null
3570 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003571 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003572 thread.bindApplication(processName, appInfo, providers,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003573 app.instrumentationClass, app.instrumentationProfileFile,
3574 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003575 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003576 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003577 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003578 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003579 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580 } catch (Exception e) {
3581 // todo: Yikes! What should we do? For now we will try to
3582 // start another process, but that could easily get us in
3583 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003584 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003585
3586 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003587 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003588 startProcessLocked(app, "bind fail", processName);
3589 return false;
3590 }
3591
3592 // Remove this record from the list of starting applications.
3593 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003594 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3595 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003596 mProcessesOnHold.remove(app);
3597
3598 boolean badApp = false;
3599 boolean didSomething = false;
3600
3601 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003602 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003603 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003604 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3605 && processName.equals(hr.processName)) {
3606 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003607 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003608 didSomething = true;
3609 }
3610 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003611 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003612 + hr.intent.getComponent().flattenToShortString(), e);
3613 badApp = true;
3614 }
3615 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003616 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 }
3618 }
3619
3620 // Find any services that should be running in this process...
3621 if (!badApp && mPendingServices.size() > 0) {
3622 ServiceRecord sr = null;
3623 try {
3624 for (int i=0; i<mPendingServices.size(); i++) {
3625 sr = mPendingServices.get(i);
3626 if (app.info.uid != sr.appInfo.uid
3627 || !processName.equals(sr.processName)) {
3628 continue;
3629 }
3630
3631 mPendingServices.remove(i);
3632 i--;
3633 realStartServiceLocked(sr, app);
3634 didSomething = true;
3635 }
3636 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003637 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 + sr.shortName, e);
3639 badApp = true;
3640 }
3641 }
3642
3643 // Check if the next broadcast receiver is in this process...
3644 BroadcastRecord br = mPendingBroadcast;
3645 if (!badApp && br != null && br.curApp == app) {
3646 try {
3647 mPendingBroadcast = null;
3648 processCurBroadcastLocked(br, app);
3649 didSomething = true;
3650 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003651 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003652 + br.curComponent.flattenToShortString(), e);
3653 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003654 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003655 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3656 br.resultExtras, br.resultAbort, true);
3657 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003658 // We need to reset the state if we fails to start the receiver.
3659 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 }
3661 }
3662
Christopher Tate181fafa2009-05-14 11:12:14 -07003663 // Check whether the next backup agent is in this process...
3664 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003665 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003666 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003667 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003668 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3669 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3670 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003671 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003672 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003673 e.printStackTrace();
3674 }
3675 }
3676
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003677 if (badApp) {
3678 // todo: Also need to kill application to deal with all
3679 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003680 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 return false;
3682 }
3683
3684 if (!didSomething) {
3685 updateOomAdjLocked();
3686 }
3687
3688 return true;
3689 }
3690
3691 public final void attachApplication(IApplicationThread thread) {
3692 synchronized (this) {
3693 int callingPid = Binder.getCallingPid();
3694 final long origId = Binder.clearCallingIdentity();
3695 attachApplicationLocked(thread, callingPid);
3696 Binder.restoreCallingIdentity(origId);
3697 }
3698 }
3699
Dianne Hackborne88846e2009-09-30 21:34:25 -07003700 public final void activityIdle(IBinder token, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003701 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003702 mMainStack.activityIdleInternal(token, false, config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003703 Binder.restoreCallingIdentity(origId);
3704 }
3705
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003706 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003707 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003708 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003709 mWindowManager.enableScreenAfterBoot();
3710 }
3711
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003712 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003713 IntentFilter pkgFilter = new IntentFilter();
3714 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3715 pkgFilter.addDataScheme("package");
3716 mContext.registerReceiver(new BroadcastReceiver() {
3717 @Override
3718 public void onReceive(Context context, Intent intent) {
3719 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3720 if (pkgs != null) {
3721 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003722 synchronized (ActivityManagerService.this) {
3723 if (forceStopPackageLocked(pkg, -1, false, false, false)) {
3724 setResultCode(Activity.RESULT_OK);
3725 return;
3726 }
3727 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003728 }
3729 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003730 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003731 }, pkgFilter);
3732
3733 synchronized (this) {
3734 // Ensure that any processes we had put on hold are now started
3735 // up.
3736 final int NP = mProcessesOnHold.size();
3737 if (NP > 0) {
3738 ArrayList<ProcessRecord> procs =
3739 new ArrayList<ProcessRecord>(mProcessesOnHold);
3740 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003741 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3742 + procs.get(ip));
3743 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003744 }
3745 }
3746
3747 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003748 // Start looking for apps that are abusing wake locks.
3749 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003750 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003751 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003752 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003753 broadcastIntentLocked(null, null,
3754 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3755 null, null, 0, null, null,
3756 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3757 false, false, MY_PID, Process.SYSTEM_UID);
3758 }
3759 }
3760 }
3761
3762 final void ensureBootCompleted() {
3763 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003764 boolean enableScreen;
3765 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003766 booting = mBooting;
3767 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003768 enableScreen = !mBooted;
3769 mBooted = true;
3770 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003771
3772 if (booting) {
3773 finishBooting();
3774 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003775
3776 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003777 enableScreenAfterBoot();
3778 }
3779 }
3780
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003781 public final void activityPaused(IBinder token) {
3782 final long origId = Binder.clearCallingIdentity();
3783 mMainStack.activityPaused(token, false);
3784 Binder.restoreCallingIdentity(origId);
3785 }
3786
3787 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3788 CharSequence description) {
3789 if (localLOGV) Slog.v(
3790 TAG, "Activity stopped: token=" + token);
3791
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003792 // Refuse possible leaked file descriptors
3793 if (icicle != null && icicle.hasFileDescriptors()) {
3794 throw new IllegalArgumentException("File descriptors passed in Bundle");
3795 }
3796
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003797 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003798
3799 final long origId = Binder.clearCallingIdentity();
3800
3801 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003802 r = mMainStack.isInStackLocked(token);
3803 if (r != null) {
3804 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003805 }
3806 }
3807
3808 if (r != null) {
3809 sendPendingThumbnail(r, null, null, null, false);
3810 }
3811
3812 trimApplications();
3813
3814 Binder.restoreCallingIdentity(origId);
3815 }
3816
3817 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003818 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003819 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003820 }
3821
3822 public String getCallingPackage(IBinder token) {
3823 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003824 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003825 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003826 }
3827 }
3828
3829 public ComponentName getCallingActivity(IBinder token) {
3830 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003831 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003832 return r != null ? r.intent.getComponent() : null;
3833 }
3834 }
3835
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003836 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003837 ActivityRecord r = mMainStack.isInStackLocked(token);
3838 if (r == null) {
3839 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003840 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003841 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003842 }
3843
3844 public ComponentName getActivityClassForToken(IBinder token) {
3845 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003846 ActivityRecord r = mMainStack.isInStackLocked(token);
3847 if (r == null) {
3848 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003850 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003851 }
3852 }
3853
3854 public String getPackageForToken(IBinder token) {
3855 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003856 ActivityRecord r = mMainStack.isInStackLocked(token);
3857 if (r == null) {
3858 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003860 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003861 }
3862 }
3863
3864 public IIntentSender getIntentSender(int type,
3865 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003866 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003867 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003868 if (intents != null) {
3869 if (intents.length < 1) {
3870 throw new IllegalArgumentException("Intents array length must be >= 1");
3871 }
3872 for (int i=0; i<intents.length; i++) {
3873 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003874 if (intent != null) {
3875 if (intent.hasFileDescriptors()) {
3876 throw new IllegalArgumentException("File descriptors passed in Intent");
3877 }
3878 if (type == INTENT_SENDER_BROADCAST &&
3879 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3880 throw new IllegalArgumentException(
3881 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3882 }
3883 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003884 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003885 }
3886 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003887 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003888 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003889 }
3890 }
3891
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003892 synchronized(this) {
3893 int callingUid = Binder.getCallingUid();
3894 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003895 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003896 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003897 .getPackageUid(packageName);
3898 if (uid != Binder.getCallingUid()) {
3899 String msg = "Permission Denial: getIntentSender() from pid="
3900 + Binder.getCallingPid()
3901 + ", uid=" + Binder.getCallingUid()
3902 + ", (need uid=" + uid + ")"
3903 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003904 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 throw new SecurityException(msg);
3906 }
3907 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003908
3909 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003910 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003912 } catch (RemoteException e) {
3913 throw new SecurityException(e);
3914 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003915 }
3916 }
3917
3918 IIntentSender getIntentSenderLocked(int type,
3919 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003920 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003921 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003922 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003923 activity = mMainStack.isInStackLocked(token);
3924 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003925 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003926 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003927 if (activity.finishing) {
3928 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003929 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003930 }
3931
3932 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3933 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3934 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3935 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3936 |PendingIntent.FLAG_UPDATE_CURRENT);
3937
3938 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3939 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003940 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003941 WeakReference<PendingIntentRecord> ref;
3942 ref = mIntentSenderRecords.get(key);
3943 PendingIntentRecord rec = ref != null ? ref.get() : null;
3944 if (rec != null) {
3945 if (!cancelCurrent) {
3946 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003947 if (rec.key.requestIntent != null) {
3948 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3949 }
3950 if (intents != null) {
3951 intents[intents.length-1] = rec.key.requestIntent;
3952 rec.key.allIntents = intents;
3953 rec.key.allResolvedTypes = resolvedTypes;
3954 } else {
3955 rec.key.allIntents = null;
3956 rec.key.allResolvedTypes = null;
3957 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003958 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 return rec;
3960 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003961 rec.canceled = true;
3962 mIntentSenderRecords.remove(key);
3963 }
3964 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 return rec;
3966 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003967 rec = new PendingIntentRecord(this, key, callingUid);
3968 mIntentSenderRecords.put(key, rec.ref);
3969 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
3970 if (activity.pendingResults == null) {
3971 activity.pendingResults
3972 = new HashSet<WeakReference<PendingIntentRecord>>();
3973 }
3974 activity.pendingResults.add(rec.ref);
3975 }
3976 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003977 }
3978
3979 public void cancelIntentSender(IIntentSender sender) {
3980 if (!(sender instanceof PendingIntentRecord)) {
3981 return;
3982 }
3983 synchronized(this) {
3984 PendingIntentRecord rec = (PendingIntentRecord)sender;
3985 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003986 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003987 .getPackageUid(rec.key.packageName);
3988 if (uid != Binder.getCallingUid()) {
3989 String msg = "Permission Denial: cancelIntentSender() from pid="
3990 + Binder.getCallingPid()
3991 + ", uid=" + Binder.getCallingUid()
3992 + " is not allowed to cancel packges "
3993 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003994 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 throw new SecurityException(msg);
3996 }
3997 } catch (RemoteException e) {
3998 throw new SecurityException(e);
3999 }
4000 cancelIntentSenderLocked(rec, true);
4001 }
4002 }
4003
4004 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4005 rec.canceled = true;
4006 mIntentSenderRecords.remove(rec.key);
4007 if (cleanActivity && rec.key.activity != null) {
4008 rec.key.activity.pendingResults.remove(rec.ref);
4009 }
4010 }
4011
4012 public String getPackageForIntentSender(IIntentSender pendingResult) {
4013 if (!(pendingResult instanceof PendingIntentRecord)) {
4014 return null;
4015 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004016 try {
4017 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4018 return res.key.packageName;
4019 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004020 }
4021 return null;
4022 }
4023
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004024 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4025 if (!(pendingResult instanceof PendingIntentRecord)) {
4026 return false;
4027 }
4028 try {
4029 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4030 if (res.key.allIntents == null) {
4031 return false;
4032 }
4033 for (int i=0; i<res.key.allIntents.length; i++) {
4034 Intent intent = res.key.allIntents[i];
4035 if (intent.getPackage() != null && intent.getComponent() != null) {
4036 return false;
4037 }
4038 }
4039 return true;
4040 } catch (ClassCastException e) {
4041 }
4042 return false;
4043 }
4044
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004045 public void setProcessLimit(int max) {
4046 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4047 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004048 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004049 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004050 mProcessLimitOverride = max;
4051 }
4052 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004053 }
4054
4055 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004056 synchronized (this) {
4057 return mProcessLimitOverride;
4058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004059 }
4060
4061 void foregroundTokenDied(ForegroundToken token) {
4062 synchronized (ActivityManagerService.this) {
4063 synchronized (mPidsSelfLocked) {
4064 ForegroundToken cur
4065 = mForegroundProcesses.get(token.pid);
4066 if (cur != token) {
4067 return;
4068 }
4069 mForegroundProcesses.remove(token.pid);
4070 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4071 if (pr == null) {
4072 return;
4073 }
4074 pr.forcingToForeground = null;
4075 pr.foregroundServices = false;
4076 }
4077 updateOomAdjLocked();
4078 }
4079 }
4080
4081 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4082 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4083 "setProcessForeground()");
4084 synchronized(this) {
4085 boolean changed = false;
4086
4087 synchronized (mPidsSelfLocked) {
4088 ProcessRecord pr = mPidsSelfLocked.get(pid);
4089 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004090 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 return;
4092 }
4093 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4094 if (oldToken != null) {
4095 oldToken.token.unlinkToDeath(oldToken, 0);
4096 mForegroundProcesses.remove(pid);
4097 pr.forcingToForeground = null;
4098 changed = true;
4099 }
4100 if (isForeground && token != null) {
4101 ForegroundToken newToken = new ForegroundToken() {
4102 public void binderDied() {
4103 foregroundTokenDied(this);
4104 }
4105 };
4106 newToken.pid = pid;
4107 newToken.token = token;
4108 try {
4109 token.linkToDeath(newToken, 0);
4110 mForegroundProcesses.put(pid, newToken);
4111 pr.forcingToForeground = token;
4112 changed = true;
4113 } catch (RemoteException e) {
4114 // If the process died while doing this, we will later
4115 // do the cleanup with the process death link.
4116 }
4117 }
4118 }
4119
4120 if (changed) {
4121 updateOomAdjLocked();
4122 }
4123 }
4124 }
4125
4126 // =========================================================
4127 // PERMISSIONS
4128 // =========================================================
4129
4130 static class PermissionController extends IPermissionController.Stub {
4131 ActivityManagerService mActivityManagerService;
4132 PermissionController(ActivityManagerService activityManagerService) {
4133 mActivityManagerService = activityManagerService;
4134 }
4135
4136 public boolean checkPermission(String permission, int pid, int uid) {
4137 return mActivityManagerService.checkPermission(permission, pid,
4138 uid) == PackageManager.PERMISSION_GRANTED;
4139 }
4140 }
4141
4142 /**
4143 * This can be called with or without the global lock held.
4144 */
4145 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004146 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 // We might be performing an operation on behalf of an indirect binder
4148 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4149 // client identity accordingly before proceeding.
4150 Identity tlsIdentity = sCallerIdentity.get();
4151 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004152 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004153 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4154 uid = tlsIdentity.uid;
4155 pid = tlsIdentity.pid;
4156 }
4157
4158 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004159 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004160 return PackageManager.PERMISSION_GRANTED;
4161 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004162 // If there is a uid that owns whatever is being accessed, it has
4163 // blanket access to it regardless of the permissions it requires.
4164 if (owningUid >= 0 && uid == owningUid) {
4165 return PackageManager.PERMISSION_GRANTED;
4166 }
4167 // If the target is not exported, then nobody else can get to it.
4168 if (!exported) {
4169 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004170 return PackageManager.PERMISSION_DENIED;
4171 }
4172 if (permission == null) {
4173 return PackageManager.PERMISSION_GRANTED;
4174 }
4175 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004176 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004177 .checkUidPermission(permission, uid);
4178 } catch (RemoteException e) {
4179 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004180 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004181 }
4182 return PackageManager.PERMISSION_DENIED;
4183 }
4184
4185 /**
4186 * As the only public entry point for permissions checking, this method
4187 * can enforce the semantic that requesting a check on a null global
4188 * permission is automatically denied. (Internally a null permission
4189 * string is used when calling {@link #checkComponentPermission} in cases
4190 * when only uid-based security is needed.)
4191 *
4192 * This can be called with or without the global lock held.
4193 */
4194 public int checkPermission(String permission, int pid, int uid) {
4195 if (permission == null) {
4196 return PackageManager.PERMISSION_DENIED;
4197 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004198 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 }
4200
4201 /**
4202 * Binder IPC calls go through the public entry point.
4203 * This can be called with or without the global lock held.
4204 */
4205 int checkCallingPermission(String permission) {
4206 return checkPermission(permission,
4207 Binder.getCallingPid(),
4208 Binder.getCallingUid());
4209 }
4210
4211 /**
4212 * This can be called with or without the global lock held.
4213 */
4214 void enforceCallingPermission(String permission, String func) {
4215 if (checkCallingPermission(permission)
4216 == PackageManager.PERMISSION_GRANTED) {
4217 return;
4218 }
4219
4220 String msg = "Permission Denial: " + func + " from pid="
4221 + Binder.getCallingPid()
4222 + ", uid=" + Binder.getCallingUid()
4223 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004224 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004225 throw new SecurityException(msg);
4226 }
4227
4228 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004229 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4230 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4231 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4232 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4233 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004234 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004235 // Is the component private from the target uid?
4236 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4237
4238 // Acceptable if the there is no read permission needed from the
4239 // target or the target is holding the read permission.
4240 if (!readPerm) {
4241 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004243 == PackageManager.PERMISSION_GRANTED)) {
4244 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004245 }
4246 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004247
4248 // Acceptable if the there is no write permission needed from the
4249 // target or the target is holding the read permission.
4250 if (!writePerm) {
4251 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004253 == PackageManager.PERMISSION_GRANTED)) {
4254 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 }
4256 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004257
4258 // Acceptable if there is a path permission matching the URI that
4259 // the target holds the permission on.
4260 PathPermission[] pps = pi.pathPermissions;
4261 if (pps != null && (!readPerm || !writePerm)) {
4262 final String path = uri.getPath();
4263 int i = pps.length;
4264 while (i > 0 && (!readPerm || !writePerm)) {
4265 i--;
4266 PathPermission pp = pps[i];
4267 if (!readPerm) {
4268 final String pprperm = pp.getReadPermission();
4269 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4270 + pprperm + " for " + pp.getPath()
4271 + ": match=" + pp.match(path)
4272 + " check=" + pm.checkUidPermission(pprperm, uid));
4273 if (pprperm != null && pp.match(path) &&
4274 (pm.checkUidPermission(pprperm, uid)
4275 == PackageManager.PERMISSION_GRANTED)) {
4276 readPerm = true;
4277 }
4278 }
4279 if (!writePerm) {
4280 final String ppwperm = pp.getWritePermission();
4281 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4282 + ppwperm + " for " + pp.getPath()
4283 + ": match=" + pp.match(path)
4284 + " check=" + pm.checkUidPermission(ppwperm, uid));
4285 if (ppwperm != null && pp.match(path) &&
4286 (pm.checkUidPermission(ppwperm, uid)
4287 == PackageManager.PERMISSION_GRANTED)) {
4288 writePerm = true;
4289 }
4290 }
4291 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004292 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004293 } catch (RemoteException e) {
4294 return false;
4295 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004296
4297 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 }
4299
4300 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4301 int modeFlags) {
4302 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004303 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 return true;
4305 }
4306 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4307 if (perms == null) return false;
4308 UriPermission perm = perms.get(uri);
4309 if (perm == null) return false;
4310 return (modeFlags&perm.modeFlags) == modeFlags;
4311 }
4312
4313 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4314 // Another redirected-binder-call permissions check as in
4315 // {@link checkComponentPermission}.
4316 Identity tlsIdentity = sCallerIdentity.get();
4317 if (tlsIdentity != null) {
4318 uid = tlsIdentity.uid;
4319 pid = tlsIdentity.pid;
4320 }
4321
4322 // Our own process gets to do everything.
4323 if (pid == MY_PID) {
4324 return PackageManager.PERMISSION_GRANTED;
4325 }
4326 synchronized(this) {
4327 return checkUriPermissionLocked(uri, uid, modeFlags)
4328 ? PackageManager.PERMISSION_GRANTED
4329 : PackageManager.PERMISSION_DENIED;
4330 }
4331 }
4332
Dianne Hackborn39792d22010-08-19 18:01:52 -07004333 /**
4334 * Check if the targetPkg can be granted permission to access uri by
4335 * the callingUid using the given modeFlags. Throws a security exception
4336 * if callingUid is not allowed to do this. Returns the uid of the target
4337 * if the URI permission grant should be performed; returns -1 if it is not
4338 * needed (for example targetPkg already has permission to access the URI).
4339 */
4340 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4341 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004342 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4343 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4344 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004345 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004346 }
4347
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004348 if (targetPkg != null) {
4349 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4350 "Checking grant " + targetPkg + " permission to " + uri);
4351 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004352
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004353 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004354
4355 // If this is not a content: uri, we can't do anything with it.
4356 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004357 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004358 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004359 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004360 }
4361
4362 String name = uri.getAuthority();
4363 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004364 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 if (cpr != null) {
4366 pi = cpr.info;
4367 } else {
4368 try {
4369 pi = pm.resolveContentProvider(name,
4370 PackageManager.GET_URI_PERMISSION_PATTERNS);
4371 } catch (RemoteException ex) {
4372 }
4373 }
4374 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004375 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004376 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 }
4378
4379 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004380 if (targetPkg != null) {
4381 try {
4382 targetUid = pm.getPackageUid(targetPkg);
4383 if (targetUid < 0) {
4384 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4385 "Can't grant URI permission no uid for: " + targetPkg);
4386 return -1;
4387 }
4388 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004389 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004391 } else {
4392 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 }
4394
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004395 if (targetUid >= 0) {
4396 // First... does the target actually need this permission?
4397 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4398 // No need to grant the target this permission.
4399 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4400 "Target " + targetPkg + " already has full permission to " + uri);
4401 return -1;
4402 }
4403 } else {
4404 // First... there is no target package, so can anyone access it?
4405 boolean allowed = pi.exported;
4406 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4407 if (pi.readPermission != null) {
4408 allowed = false;
4409 }
4410 }
4411 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4412 if (pi.writePermission != null) {
4413 allowed = false;
4414 }
4415 }
4416 if (allowed) {
4417 return -1;
4418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 }
4420
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004421 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 if (!pi.grantUriPermissions) {
4423 throw new SecurityException("Provider " + pi.packageName
4424 + "/" + pi.name
4425 + " does not allow granting of Uri permissions (uri "
4426 + uri + ")");
4427 }
4428 if (pi.uriPermissionPatterns != null) {
4429 final int N = pi.uriPermissionPatterns.length;
4430 boolean allowed = false;
4431 for (int i=0; i<N; i++) {
4432 if (pi.uriPermissionPatterns[i] != null
4433 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4434 allowed = true;
4435 break;
4436 }
4437 }
4438 if (!allowed) {
4439 throw new SecurityException("Provider " + pi.packageName
4440 + "/" + pi.name
4441 + " does not allow granting of permission to path of Uri "
4442 + uri);
4443 }
4444 }
4445
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004446 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004448 if (callingUid != Process.myUid()) {
4449 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4450 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4451 throw new SecurityException("Uid " + callingUid
4452 + " does not have permission to uri " + uri);
4453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004454 }
4455 }
4456
Dianne Hackborn39792d22010-08-19 18:01:52 -07004457 return targetUid;
4458 }
4459
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004460 public int checkGrantUriPermission(int callingUid, String targetPkg,
4461 Uri uri, int modeFlags) {
4462 synchronized(this) {
4463 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4464 }
4465 }
4466
Dianne Hackborn39792d22010-08-19 18:01:52 -07004467 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4468 Uri uri, int modeFlags, UriPermissionOwner owner) {
4469 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4470 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4471 if (modeFlags == 0) {
4472 return;
4473 }
4474
4475 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 // to the uri, and the target doesn't. Let's now give this to
4477 // the target.
4478
Joe Onorato8a9b2202010-02-26 18:56:32 -08004479 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004480 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004481
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004482 HashMap<Uri, UriPermission> targetUris
4483 = mGrantedUriPermissions.get(targetUid);
4484 if (targetUris == null) {
4485 targetUris = new HashMap<Uri, UriPermission>();
4486 mGrantedUriPermissions.put(targetUid, targetUris);
4487 }
4488
4489 UriPermission perm = targetUris.get(uri);
4490 if (perm == null) {
4491 perm = new UriPermission(targetUid, uri);
4492 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004496 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004498 } else {
4499 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4500 perm.readOwners.add(owner);
4501 owner.addReadPermission(perm);
4502 }
4503 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4504 perm.writeOwners.add(owner);
4505 owner.addWritePermission(perm);
4506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 }
4508 }
4509
Dianne Hackborn39792d22010-08-19 18:01:52 -07004510 void grantUriPermissionLocked(int callingUid,
4511 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004512 if (targetPkg == null) {
4513 throw new NullPointerException("targetPkg");
4514 }
4515
Dianne Hackborn39792d22010-08-19 18:01:52 -07004516 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4517 if (targetUid < 0) {
4518 return;
4519 }
4520
4521 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4522 }
4523
4524 /**
4525 * Like checkGrantUriPermissionLocked, but takes an Intent.
4526 */
4527 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4528 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004529 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004530 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004531 + " from " + intent + "; flags=0x"
4532 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4533
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004534 if (targetPkg == null) {
4535 throw new NullPointerException("targetPkg");
4536 }
4537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004539 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 }
4541 Uri data = intent.getData();
4542 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004543 return -1;
4544 }
4545 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4546 intent.getFlags());
4547 }
4548
4549 /**
4550 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4551 */
4552 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4553 String targetPkg, Intent intent, UriPermissionOwner owner) {
4554 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4555 intent.getFlags(), owner);
4556 }
4557
4558 void grantUriPermissionFromIntentLocked(int callingUid,
4559 String targetPkg, Intent intent, UriPermissionOwner owner) {
4560 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4561 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 return;
4563 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004564
4565 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004566 }
4567
4568 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4569 Uri uri, int modeFlags) {
4570 synchronized(this) {
4571 final ProcessRecord r = getRecordForAppLocked(caller);
4572 if (r == null) {
4573 throw new SecurityException("Unable to find app for caller "
4574 + caller
4575 + " when granting permission to uri " + uri);
4576 }
4577 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004578 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004579 }
4580 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004581 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004582 }
4583
4584 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4585 null);
4586 }
4587 }
4588
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004589 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004590 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4591 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4592 HashMap<Uri, UriPermission> perms
4593 = mGrantedUriPermissions.get(perm.uid);
4594 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004595 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004596 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004597 perms.remove(perm.uri);
4598 if (perms.size() == 0) {
4599 mGrantedUriPermissions.remove(perm.uid);
4600 }
4601 }
4602 }
4603 }
4604
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4606 int modeFlags) {
4607 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4608 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4609 if (modeFlags == 0) {
4610 return;
4611 }
4612
Joe Onorato8a9b2202010-02-26 18:56:32 -08004613 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004614 "Revoking all granted permissions to " + uri);
4615
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004616 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004617
4618 final String authority = uri.getAuthority();
4619 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004620 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 if (cpr != null) {
4622 pi = cpr.info;
4623 } else {
4624 try {
4625 pi = pm.resolveContentProvider(authority,
4626 PackageManager.GET_URI_PERMISSION_PATTERNS);
4627 } catch (RemoteException ex) {
4628 }
4629 }
4630 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004631 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004632 return;
4633 }
4634
4635 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004636 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004637 // Right now, if you are not the original owner of the permission,
4638 // you are not allowed to revoke it.
4639 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4640 throw new SecurityException("Uid " + callingUid
4641 + " does not have permission to uri " + uri);
4642 //}
4643 }
4644
4645 // Go through all of the permissions and remove any that match.
4646 final List<String> SEGMENTS = uri.getPathSegments();
4647 if (SEGMENTS != null) {
4648 final int NS = SEGMENTS.size();
4649 int N = mGrantedUriPermissions.size();
4650 for (int i=0; i<N; i++) {
4651 HashMap<Uri, UriPermission> perms
4652 = mGrantedUriPermissions.valueAt(i);
4653 Iterator<UriPermission> it = perms.values().iterator();
4654 toploop:
4655 while (it.hasNext()) {
4656 UriPermission perm = it.next();
4657 Uri targetUri = perm.uri;
4658 if (!authority.equals(targetUri.getAuthority())) {
4659 continue;
4660 }
4661 List<String> targetSegments = targetUri.getPathSegments();
4662 if (targetSegments == null) {
4663 continue;
4664 }
4665 if (targetSegments.size() < NS) {
4666 continue;
4667 }
4668 for (int j=0; j<NS; j++) {
4669 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4670 continue toploop;
4671 }
4672 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004673 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004674 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004675 perm.clearModes(modeFlags);
4676 if (perm.modeFlags == 0) {
4677 it.remove();
4678 }
4679 }
4680 if (perms.size() == 0) {
4681 mGrantedUriPermissions.remove(
4682 mGrantedUriPermissions.keyAt(i));
4683 N--;
4684 i--;
4685 }
4686 }
4687 }
4688 }
4689
4690 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4691 int modeFlags) {
4692 synchronized(this) {
4693 final ProcessRecord r = getRecordForAppLocked(caller);
4694 if (r == null) {
4695 throw new SecurityException("Unable to find app for caller "
4696 + caller
4697 + " when revoking permission to uri " + uri);
4698 }
4699 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004700 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004701 return;
4702 }
4703
4704 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4705 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4706 if (modeFlags == 0) {
4707 return;
4708 }
4709
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004710 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711
4712 final String authority = uri.getAuthority();
4713 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004714 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004715 if (cpr != null) {
4716 pi = cpr.info;
4717 } else {
4718 try {
4719 pi = pm.resolveContentProvider(authority,
4720 PackageManager.GET_URI_PERMISSION_PATTERNS);
4721 } catch (RemoteException ex) {
4722 }
4723 }
4724 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004725 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004726 return;
4727 }
4728
4729 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4730 }
4731 }
4732
Dianne Hackborn7e269642010-08-25 19:50:20 -07004733 @Override
4734 public IBinder newUriPermissionOwner(String name) {
4735 synchronized(this) {
4736 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4737 return owner.getExternalTokenLocked();
4738 }
4739 }
4740
4741 @Override
4742 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4743 Uri uri, int modeFlags) {
4744 synchronized(this) {
4745 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4746 if (owner == null) {
4747 throw new IllegalArgumentException("Unknown owner: " + token);
4748 }
4749 if (fromUid != Binder.getCallingUid()) {
4750 if (Binder.getCallingUid() != Process.myUid()) {
4751 // Only system code can grant URI permissions on behalf
4752 // of other users.
4753 throw new SecurityException("nice try");
4754 }
4755 }
4756 if (targetPkg == null) {
4757 throw new IllegalArgumentException("null target");
4758 }
4759 if (uri == null) {
4760 throw new IllegalArgumentException("null uri");
4761 }
4762
4763 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4764 }
4765 }
4766
4767 @Override
4768 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4769 synchronized(this) {
4770 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4771 if (owner == null) {
4772 throw new IllegalArgumentException("Unknown owner: " + token);
4773 }
4774
4775 if (uri == null) {
4776 owner.removeUriPermissionsLocked(mode);
4777 } else {
4778 owner.removeUriPermissionLocked(uri, mode);
4779 }
4780 }
4781 }
4782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004783 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4784 synchronized (this) {
4785 ProcessRecord app =
4786 who != null ? getRecordForAppLocked(who) : null;
4787 if (app == null) return;
4788
4789 Message msg = Message.obtain();
4790 msg.what = WAIT_FOR_DEBUGGER_MSG;
4791 msg.obj = app;
4792 msg.arg1 = waiting ? 1 : 0;
4793 mHandler.sendMessage(msg);
4794 }
4795 }
4796
4797 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004798 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4799 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004801 outInfo.threshold = homeAppMem;
4802 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4803 outInfo.hiddenAppThreshold = hiddenAppMem;
4804 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4805 ProcessList.SECONDARY_SERVER_ADJ);
4806 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4807 ProcessList.VISIBLE_APP_ADJ);
4808 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4809 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004810 }
4811
4812 // =========================================================
4813 // TASK MANAGEMENT
4814 // =========================================================
4815
4816 public List getTasks(int maxNum, int flags,
4817 IThumbnailReceiver receiver) {
4818 ArrayList list = new ArrayList();
4819
4820 PendingThumbnailsRecord pending = null;
4821 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004822 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004823
4824 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004825 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004826 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4827 + ", receiver=" + receiver);
4828
4829 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4830 != PackageManager.PERMISSION_GRANTED) {
4831 if (receiver != null) {
4832 // If the caller wants to wait for pending thumbnails,
4833 // it ain't gonna get them.
4834 try {
4835 receiver.finished();
4836 } catch (RemoteException ex) {
4837 }
4838 }
4839 String msg = "Permission Denial: getTasks() from pid="
4840 + Binder.getCallingPid()
4841 + ", uid=" + Binder.getCallingUid()
4842 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004843 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 throw new SecurityException(msg);
4845 }
4846
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004847 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004848 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004849 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004850 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 TaskRecord curTask = null;
4852 int numActivities = 0;
4853 int numRunning = 0;
4854 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004855 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004856 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004857 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858
4859 // Initialize state for next task if needed.
4860 if (top == null ||
4861 (top.state == ActivityState.INITIALIZING
4862 && top.task == r.task)) {
4863 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004864 curTask = r.task;
4865 numActivities = numRunning = 0;
4866 }
4867
4868 // Add 'r' into the current task.
4869 numActivities++;
4870 if (r.app != null && r.app.thread != null) {
4871 numRunning++;
4872 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004873
Joe Onorato8a9b2202010-02-26 18:56:32 -08004874 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004875 TAG, r.intent.getComponent().flattenToShortString()
4876 + ": task=" + r.task);
4877
4878 // If the next one is a different task, generate a new
4879 // TaskInfo entry for what we have.
4880 if (next == null || next.task != curTask) {
4881 ActivityManager.RunningTaskInfo ci
4882 = new ActivityManager.RunningTaskInfo();
4883 ci.id = curTask.taskId;
4884 ci.baseActivity = r.intent.getComponent();
4885 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004886 if (top.thumbHolder != null) {
4887 ci.description = top.thumbHolder.lastDescription;
4888 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004889 ci.numActivities = numActivities;
4890 ci.numRunning = numRunning;
4891 //System.out.println(
4892 // "#" + maxNum + ": " + " descr=" + ci.description);
4893 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004894 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895 TAG, "State=" + top.state + "Idle=" + top.idle
4896 + " app=" + top.app
4897 + " thr=" + (top.app != null ? top.app.thread : null));
4898 if (top.state == ActivityState.RESUMED
4899 || top.state == ActivityState.PAUSING) {
4900 if (top.idle && top.app != null
4901 && top.app.thread != null) {
4902 topRecord = top;
4903 topThumbnail = top.app.thread;
4904 } else {
4905 top.thumbnailNeeded = true;
4906 }
4907 }
4908 if (pending == null) {
4909 pending = new PendingThumbnailsRecord(receiver);
4910 }
4911 pending.pendingRecords.add(top);
4912 }
4913 list.add(ci);
4914 maxNum--;
4915 top = null;
4916 }
4917 }
4918
4919 if (pending != null) {
4920 mPendingThumbnails.add(pending);
4921 }
4922 }
4923
Joe Onorato8a9b2202010-02-26 18:56:32 -08004924 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925
4926 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004927 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928 try {
4929 topThumbnail.requestThumbnail(topRecord);
4930 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004931 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 sendPendingThumbnail(null, topRecord, null, null, true);
4933 }
4934 }
4935
4936 if (pending == null && receiver != null) {
4937 // In this case all thumbnails were available and the client
4938 // is being asked to be told when the remaining ones come in...
4939 // which is unusually, since the top-most currently running
4940 // activity should never have a canned thumbnail! Oh well.
4941 try {
4942 receiver.finished();
4943 } catch (RemoteException ex) {
4944 }
4945 }
4946
4947 return list;
4948 }
4949
4950 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4951 int flags) {
4952 synchronized (this) {
4953 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4954 "getRecentTasks()");
4955
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004956 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004958 final int N = mRecentTasks.size();
4959 ArrayList<ActivityManager.RecentTaskInfo> res
4960 = new ArrayList<ActivityManager.RecentTaskInfo>(
4961 maxNum < N ? maxNum : N);
4962 for (int i=0; i<N && maxNum > 0; i++) {
4963 TaskRecord tr = mRecentTasks.get(i);
4964 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
4965 || (tr.intent == null)
4966 || ((tr.intent.getFlags()
4967 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
4968 ActivityManager.RecentTaskInfo rti
4969 = new ActivityManager.RecentTaskInfo();
4970 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08004971 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004972 rti.baseIntent = new Intent(
4973 tr.intent != null ? tr.intent : tr.affinityIntent);
4974 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08004975 rti.description = tr.lastDescription;
4976
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004977 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
4978 // Check whether this activity is currently available.
4979 try {
4980 if (rti.origActivity != null) {
4981 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
4982 continue;
4983 }
4984 } else if (rti.baseIntent != null) {
4985 if (pm.queryIntentActivities(rti.baseIntent,
4986 null, 0) == null) {
4987 continue;
4988 }
4989 }
4990 } catch (RemoteException e) {
4991 // Will never happen.
4992 }
4993 }
4994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004995 res.add(rti);
4996 maxNum--;
4997 }
4998 }
4999 return res;
5000 }
5001 }
5002
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005003 private TaskRecord taskForIdLocked(int id) {
5004 final int N = mRecentTasks.size();
5005 for (int i=0; i<N; i++) {
5006 TaskRecord tr = mRecentTasks.get(i);
5007 if (tr.taskId == id) {
5008 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005009 }
5010 }
5011 return null;
5012 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005013
5014 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5015 synchronized (this) {
5016 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5017 "getTaskThumbnails()");
5018 TaskRecord tr = taskForIdLocked(id);
5019 if (tr != null) {
5020 return mMainStack.getTaskThumbnailsLocked(tr);
5021 }
5022 }
5023 return null;
5024 }
5025
5026 public boolean removeSubTask(int taskId, int subTaskIndex) {
5027 synchronized (this) {
5028 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5029 "removeSubTask()");
5030 long ident = Binder.clearCallingIdentity();
5031 try {
5032 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5033 } finally {
5034 Binder.restoreCallingIdentity(ident);
5035 }
5036 }
5037 }
5038
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005039 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005040 TaskRecord tr = root.task;
5041 Intent baseIntent = new Intent(
5042 tr.intent != null ? tr.intent : tr.affinityIntent);
5043 ComponentName component = baseIntent.getComponent();
5044 if (component == null) {
5045 Slog.w(TAG, "Now component for base intent of task: " + tr);
5046 return;
5047 }
5048
5049 // Find any running services associated with this app.
5050 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5051 for (ServiceRecord sr : mServices.values()) {
5052 if (sr.packageName.equals(component.getPackageName())) {
5053 services.add(sr);
5054 }
5055 }
5056
5057 // Take care of any running services associated with the app.
5058 for (int i=0; i<services.size(); i++) {
5059 ServiceRecord sr = services.get(i);
5060 if (sr.startRequested) {
5061 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005062 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005063 stopServiceLocked(sr);
5064 } else {
5065 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5066 sr.makeNextStartId(), baseIntent, -1));
5067 if (sr.app != null && sr.app.thread != null) {
5068 sendServiceArgsLocked(sr, false);
5069 }
5070 }
5071 }
5072 }
5073
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005074 if (killProcesses) {
5075 // Find any running processes associated with this app.
5076 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5077 SparseArray<ProcessRecord> appProcs
5078 = mProcessNames.getMap().get(component.getPackageName());
5079 if (appProcs != null) {
5080 for (int i=0; i<appProcs.size(); i++) {
5081 procs.add(appProcs.valueAt(i));
5082 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005083 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005084
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005085 // Kill the running processes.
5086 for (int i=0; i<procs.size(); i++) {
5087 ProcessRecord pr = procs.get(i);
5088 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5089 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5090 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5091 pr.processName, pr.setAdj, "remove task");
5092 Process.killProcessQuiet(pr.pid);
5093 } else {
5094 pr.waitingToKill = "remove task";
5095 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005096 }
5097 }
5098 }
5099
5100 public boolean removeTask(int taskId, int flags) {
5101 synchronized (this) {
5102 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5103 "removeTask()");
5104 long ident = Binder.clearCallingIdentity();
5105 try {
5106 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5107 if (r != null) {
5108 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005109 cleanUpRemovedTaskLocked(r,
5110 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005111 return true;
5112 }
5113 } finally {
5114 Binder.restoreCallingIdentity(ident);
5115 }
5116 }
5117 return false;
5118 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005119
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005120 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5121 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005122 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005123 TaskRecord jt = startTask;
5124
5125 // First look backwards
5126 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005127 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005128 if (r.task != jt) {
5129 jt = r.task;
5130 if (affinity.equals(jt.affinity)) {
5131 return j;
5132 }
5133 }
5134 }
5135
5136 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005137 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005138 jt = startTask;
5139 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005140 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005141 if (r.task != jt) {
5142 if (affinity.equals(jt.affinity)) {
5143 return j;
5144 }
5145 jt = r.task;
5146 }
5147 }
5148
5149 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005150 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005151 return N-1;
5152 }
5153
5154 return -1;
5155 }
5156
5157 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005158 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005160 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5162 "moveTaskToFront()");
5163
5164 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005165 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5166 Binder.getCallingUid(), "Task to front")) {
5167 return;
5168 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005169 final long origId = Binder.clearCallingIdentity();
5170 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005171 TaskRecord tr = taskForIdLocked(task);
5172 if (tr != null) {
5173 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5174 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005175 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005176 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5177 // Caller wants the home activity moved with it. To accomplish this,
5178 // we'll just move the home task to the top first.
5179 mMainStack.moveHomeToFrontLocked();
5180 }
5181 mMainStack.moveTaskToFrontLocked(tr, null);
5182 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005183 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005184 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5185 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005186 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005187 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5188 mMainStack.mUserLeaving = true;
5189 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005190 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5191 // Caller wants the home activity moved with it. To accomplish this,
5192 // we'll just move the home task to the top first.
5193 mMainStack.moveHomeToFrontLocked();
5194 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005195 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 return;
5197 }
5198 }
5199 } finally {
5200 Binder.restoreCallingIdentity(origId);
5201 }
5202 }
5203 }
5204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005205 public void moveTaskToBack(int task) {
5206 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5207 "moveTaskToBack()");
5208
5209 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005210 if (mMainStack.mResumedActivity != null
5211 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005212 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5213 Binder.getCallingUid(), "Task to back")) {
5214 return;
5215 }
5216 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005217 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005218 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 Binder.restoreCallingIdentity(origId);
5220 }
5221 }
5222
5223 /**
5224 * Moves an activity, and all of the other activities within the same task, to the bottom
5225 * of the history stack. The activity's order within the task is unchanged.
5226 *
5227 * @param token A reference to the activity we wish to move
5228 * @param nonRoot If false then this only works if the activity is the root
5229 * of a task; if true it will work for any activity in a task.
5230 * @return Returns true if the move completed, false if not.
5231 */
5232 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5233 synchronized(this) {
5234 final long origId = Binder.clearCallingIdentity();
5235 int taskId = getTaskForActivityLocked(token, !nonRoot);
5236 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005237 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005238 }
5239 Binder.restoreCallingIdentity(origId);
5240 }
5241 return false;
5242 }
5243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 public void moveTaskBackwards(int task) {
5245 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5246 "moveTaskBackwards()");
5247
5248 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005249 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5250 Binder.getCallingUid(), "Task backwards")) {
5251 return;
5252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005253 final long origId = Binder.clearCallingIdentity();
5254 moveTaskBackwardsLocked(task);
5255 Binder.restoreCallingIdentity(origId);
5256 }
5257 }
5258
5259 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005260 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 }
5262
5263 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5264 synchronized(this) {
5265 return getTaskForActivityLocked(token, onlyRoot);
5266 }
5267 }
5268
5269 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005270 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005271 TaskRecord lastTask = null;
5272 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005273 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005274 if (r == token) {
5275 if (!onlyRoot || lastTask != r.task) {
5276 return r.task.taskId;
5277 }
5278 return -1;
5279 }
5280 lastTask = r.task;
5281 }
5282
5283 return -1;
5284 }
5285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005286 public void finishOtherInstances(IBinder token, ComponentName className) {
5287 synchronized(this) {
5288 final long origId = Binder.clearCallingIdentity();
5289
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005290 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005291 TaskRecord lastTask = null;
5292 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005293 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005294 if (r.realActivity.equals(className)
5295 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005296 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005297 null, "others")) {
5298 i--;
5299 N--;
5300 }
5301 }
5302 lastTask = r.task;
5303 }
5304
5305 Binder.restoreCallingIdentity(origId);
5306 }
5307 }
5308
5309 // =========================================================
5310 // THUMBNAILS
5311 // =========================================================
5312
5313 public void reportThumbnail(IBinder token,
5314 Bitmap thumbnail, CharSequence description) {
5315 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5316 final long origId = Binder.clearCallingIdentity();
5317 sendPendingThumbnail(null, token, thumbnail, description, true);
5318 Binder.restoreCallingIdentity(origId);
5319 }
5320
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005321 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005322 Bitmap thumbnail, CharSequence description, boolean always) {
5323 TaskRecord task = null;
5324 ArrayList receivers = null;
5325
5326 //System.out.println("Send pending thumbnail: " + r);
5327
5328 synchronized(this) {
5329 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005330 r = mMainStack.isInStackLocked(token);
5331 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005332 return;
5333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005335 if (thumbnail == null && r.thumbHolder != null) {
5336 thumbnail = r.thumbHolder.lastThumbnail;
5337 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005338 }
5339 if (thumbnail == null && !always) {
5340 // If there is no thumbnail, and this entry is not actually
5341 // going away, then abort for now and pick up the next
5342 // thumbnail we get.
5343 return;
5344 }
5345 task = r.task;
5346
5347 int N = mPendingThumbnails.size();
5348 int i=0;
5349 while (i<N) {
5350 PendingThumbnailsRecord pr =
5351 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5352 //System.out.println("Looking in " + pr.pendingRecords);
5353 if (pr.pendingRecords.remove(r)) {
5354 if (receivers == null) {
5355 receivers = new ArrayList();
5356 }
5357 receivers.add(pr);
5358 if (pr.pendingRecords.size() == 0) {
5359 pr.finished = true;
5360 mPendingThumbnails.remove(i);
5361 N--;
5362 continue;
5363 }
5364 }
5365 i++;
5366 }
5367 }
5368
5369 if (receivers != null) {
5370 final int N = receivers.size();
5371 for (int i=0; i<N; i++) {
5372 try {
5373 PendingThumbnailsRecord pr =
5374 (PendingThumbnailsRecord)receivers.get(i);
5375 pr.receiver.newThumbnail(
5376 task != null ? task.taskId : -1, thumbnail, description);
5377 if (pr.finished) {
5378 pr.receiver.finished();
5379 }
5380 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005381 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 }
5383 }
5384 }
5385 }
5386
5387 // =========================================================
5388 // CONTENT PROVIDERS
5389 // =========================================================
5390
Jeff Brown10e89712011-07-08 18:52:57 -07005391 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5392 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005394 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005395 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005396 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005397 } catch (RemoteException ex) {
5398 }
5399 if (providers != null) {
5400 final int N = providers.size();
5401 for (int i=0; i<N; i++) {
5402 ProviderInfo cpi =
5403 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005404 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005405 if (cpr == null) {
5406 cpr = new ContentProviderRecord(cpi, app.info);
5407 mProvidersByClass.put(cpi.name, cpr);
5408 }
5409 app.pubProviders.put(cpi.name, cpr);
5410 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005411 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005412 }
5413 }
5414 return providers;
5415 }
5416
5417 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005418 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005419 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5420 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5421 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005422 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005423 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005424 return null;
5425 }
5426 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005427 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005428 == PackageManager.PERMISSION_GRANTED) {
5429 return null;
5430 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005431
5432 PathPermission[] pps = cpi.pathPermissions;
5433 if (pps != null) {
5434 int i = pps.length;
5435 while (i > 0) {
5436 i--;
5437 PathPermission pp = pps[i];
5438 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005439 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005440 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005441 return null;
5442 }
5443 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005444 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005445 == PackageManager.PERMISSION_GRANTED) {
5446 return null;
5447 }
5448 }
5449 }
5450
Dianne Hackbornb424b632010-08-18 15:59:05 -07005451 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5452 if (perms != null) {
5453 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5454 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5455 return null;
5456 }
5457 }
5458 }
5459
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005460 String msg;
5461 if (!cpi.exported) {
5462 msg = "Permission Denial: opening provider " + cpi.name
5463 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5464 + ", uid=" + callingUid + ") that is not exported from uid "
5465 + cpi.applicationInfo.uid;
5466 } else {
5467 msg = "Permission Denial: opening provider " + cpi.name
5468 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5469 + ", uid=" + callingUid + ") requires "
5470 + cpi.readPermission + " or " + cpi.writePermission;
5471 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005472 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005473 return msg;
5474 }
5475
5476 private final ContentProviderHolder getContentProviderImpl(
5477 IApplicationThread caller, String name) {
5478 ContentProviderRecord cpr;
5479 ProviderInfo cpi = null;
5480
5481 synchronized(this) {
5482 ProcessRecord r = null;
5483 if (caller != null) {
5484 r = getRecordForAppLocked(caller);
5485 if (r == null) {
5486 throw new SecurityException(
5487 "Unable to find app for caller " + caller
5488 + " (pid=" + Binder.getCallingPid()
5489 + ") when getting content provider " + name);
5490 }
5491 }
5492
5493 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005494 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005495 if (cpr != null) {
5496 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005497 String msg;
5498 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5499 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005500 }
5501
5502 if (r != null && cpr.canRunHere(r)) {
5503 // This provider has been published or is in the process
5504 // of being published... but it is also allowed to run
5505 // in the caller's process, so don't make a connection
5506 // and just let the caller instantiate its own instance.
5507 if (cpr.provider != null) {
5508 // don't give caller the provider object, it needs
5509 // to make its own.
5510 cpr = new ContentProviderRecord(cpr);
5511 }
5512 return cpr;
5513 }
5514
5515 final long origId = Binder.clearCallingIdentity();
5516
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005517 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005518 // return it right away.
5519 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005520 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005521 "Adding provider requested by "
5522 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005523 + cpr.info.processName);
5524 Integer cnt = r.conProviders.get(cpr);
5525 if (cnt == null) {
5526 r.conProviders.put(cpr, new Integer(1));
5527 } else {
5528 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005530 cpr.clients.add(r);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005531 if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005532 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005533 // make sure to count it as being accessed and thus
5534 // back up on the LRU list. This is good because
5535 // content providers are often expensive to start.
5536 updateLruProcessLocked(cpr.app, false, true);
5537 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005538 } else {
5539 cpr.externals++;
5540 }
5541
5542 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005543 updateOomAdjLocked(cpr.app);
5544 }
5545
5546 Binder.restoreCallingIdentity(origId);
5547
5548 } else {
5549 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005550 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005551 resolveContentProvider(name,
5552 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005553 } catch (RemoteException ex) {
5554 }
5555 if (cpi == null) {
5556 return null;
5557 }
5558
Dianne Hackbornb424b632010-08-18 15:59:05 -07005559 String msg;
5560 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5561 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005562 }
5563
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005564 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005565 && !cpi.processName.equals("system")) {
5566 // If this content provider does not run in the system
5567 // process, and the system is not yet ready to run other
5568 // processes, then fail fast instead of hanging.
5569 throw new IllegalArgumentException(
5570 "Attempt to launch content provider before system ready");
5571 }
5572
Dianne Hackborn860755f2010-06-03 18:47:52 -07005573 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 final boolean firstClass = cpr == null;
5575 if (firstClass) {
5576 try {
5577 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005578 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005579 getApplicationInfo(
5580 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005581 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005583 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005584 + cpi.name);
5585 return null;
5586 }
5587 cpr = new ContentProviderRecord(cpi, ai);
5588 } catch (RemoteException ex) {
5589 // pm is in same process, this will never happen.
5590 }
5591 }
5592
5593 if (r != null && cpr.canRunHere(r)) {
5594 // If this is a multiprocess provider, then just return its
5595 // info and allow the caller to instantiate it. Only do
5596 // this if the provider is the same user as the caller's
5597 // process, or can run as root (so can be in any process).
5598 return cpr;
5599 }
5600
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005601 if (DEBUG_PROVIDER) {
5602 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005603 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005604 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 }
5606
5607 // This is single process, and our app is now connecting to it.
5608 // See if we are already in the process of launching this
5609 // provider.
5610 final int N = mLaunchingProviders.size();
5611 int i;
5612 for (i=0; i<N; i++) {
5613 if (mLaunchingProviders.get(i) == cpr) {
5614 break;
5615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005616 }
5617
5618 // If the provider is not already being launched, then get it
5619 // started.
5620 if (i >= N) {
5621 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005622
5623 try {
5624 // Content provider is now in use, its package can't be stopped.
5625 try {
5626 AppGlobals.getPackageManager().setPackageStoppedState(
5627 cpr.appInfo.packageName, false);
5628 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005629 } catch (IllegalArgumentException e) {
5630 Slog.w(TAG, "Failed trying to unstop package "
5631 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005632 }
5633
5634 ProcessRecord proc = startProcessLocked(cpi.processName,
5635 cpr.appInfo, false, 0, "content provider",
5636 new ComponentName(cpi.applicationInfo.packageName,
5637 cpi.name), false);
5638 if (proc == null) {
5639 Slog.w(TAG, "Unable to launch app "
5640 + cpi.applicationInfo.packageName + "/"
5641 + cpi.applicationInfo.uid + " for provider "
5642 + name + ": process is bad");
5643 return null;
5644 }
5645 cpr.launchingApp = proc;
5646 mLaunchingProviders.add(cpr);
5647 } finally {
5648 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005649 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005650 }
5651
5652 // Make sure the provider is published (the same provider class
5653 // may be published under multiple names).
5654 if (firstClass) {
5655 mProvidersByClass.put(cpi.name, cpr);
5656 }
5657 mProvidersByName.put(name, cpr);
5658
5659 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005660 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005661 "Adding provider requested by "
5662 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005663 + cpr.info.processName);
5664 Integer cnt = r.conProviders.get(cpr);
5665 if (cnt == null) {
5666 r.conProviders.put(cpr, new Integer(1));
5667 } else {
5668 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5669 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005670 cpr.clients.add(r);
5671 } else {
5672 cpr.externals++;
5673 }
5674 }
5675 }
5676
5677 // Wait for the provider to be published...
5678 synchronized (cpr) {
5679 while (cpr.provider == null) {
5680 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005681 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005682 + cpi.applicationInfo.packageName + "/"
5683 + cpi.applicationInfo.uid + " for provider "
5684 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005685 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005686 cpi.applicationInfo.packageName,
5687 cpi.applicationInfo.uid, name);
5688 return null;
5689 }
5690 try {
5691 cpr.wait();
5692 } catch (InterruptedException ex) {
5693 }
5694 }
5695 }
5696 return cpr;
5697 }
5698
5699 public final ContentProviderHolder getContentProvider(
5700 IApplicationThread caller, String name) {
5701 if (caller == null) {
5702 String msg = "null IApplicationThread when getting content provider "
5703 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005704 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005705 throw new SecurityException(msg);
5706 }
5707
5708 return getContentProviderImpl(caller, name);
5709 }
5710
5711 private ContentProviderHolder getContentProviderExternal(String name) {
5712 return getContentProviderImpl(null, name);
5713 }
5714
5715 /**
5716 * Drop a content provider from a ProcessRecord's bookkeeping
5717 * @param cpr
5718 */
5719 public void removeContentProvider(IApplicationThread caller, String name) {
5720 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005721 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005722 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005723 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005724 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005725 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 return;
5727 }
5728 final ProcessRecord r = getRecordForAppLocked(caller);
5729 if (r == null) {
5730 throw new SecurityException(
5731 "Unable to find app for caller " + caller +
5732 " when removing content provider " + name);
5733 }
5734 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005735 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005736 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005737 + r.info.processName + " from process "
5738 + localCpr.appInfo.processName);
5739 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005740 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005741 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005742 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005743 return;
5744 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005745 Integer cnt = r.conProviders.get(localCpr);
5746 if (cnt == null || cnt.intValue() <= 1) {
5747 localCpr.clients.remove(r);
5748 r.conProviders.remove(localCpr);
5749 } else {
5750 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5751 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005752 }
5753 updateOomAdjLocked();
5754 }
5755 }
5756
5757 private void removeContentProviderExternal(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) {
5761 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005762 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 return;
5764 }
5765
5766 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005767 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005768 localCpr.externals--;
5769 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005770 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005771 }
5772 updateOomAdjLocked();
5773 }
5774 }
5775
5776 public final void publishContentProviders(IApplicationThread caller,
5777 List<ContentProviderHolder> providers) {
5778 if (providers == null) {
5779 return;
5780 }
5781
5782 synchronized(this) {
5783 final ProcessRecord r = getRecordForAppLocked(caller);
5784 if (r == null) {
5785 throw new SecurityException(
5786 "Unable to find app for caller " + caller
5787 + " (pid=" + Binder.getCallingPid()
5788 + ") when publishing content providers");
5789 }
5790
5791 final long origId = Binder.clearCallingIdentity();
5792
5793 final int N = providers.size();
5794 for (int i=0; i<N; i++) {
5795 ContentProviderHolder src = providers.get(i);
5796 if (src == null || src.info == null || src.provider == null) {
5797 continue;
5798 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005799 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005800 if (dst != null) {
5801 mProvidersByClass.put(dst.info.name, dst);
5802 String names[] = dst.info.authority.split(";");
5803 for (int j = 0; j < names.length; j++) {
5804 mProvidersByName.put(names[j], dst);
5805 }
5806
5807 int NL = mLaunchingProviders.size();
5808 int j;
5809 for (j=0; j<NL; j++) {
5810 if (mLaunchingProviders.get(j) == dst) {
5811 mLaunchingProviders.remove(j);
5812 j--;
5813 NL--;
5814 }
5815 }
5816 synchronized (dst) {
5817 dst.provider = src.provider;
5818 dst.app = r;
5819 dst.notifyAll();
5820 }
5821 updateOomAdjLocked(r);
5822 }
5823 }
5824
5825 Binder.restoreCallingIdentity(origId);
5826 }
5827 }
5828
5829 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005830 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005831 synchronized (mSelf) {
5832 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5833 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005834 if (providers != null) {
5835 for (int i=providers.size()-1; i>=0; i--) {
5836 ProviderInfo pi = (ProviderInfo)providers.get(i);
5837 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5838 Slog.w(TAG, "Not installing system proc provider " + pi.name
5839 + ": not system .apk");
5840 providers.remove(i);
5841 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005842 }
5843 }
5844 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005845 if (providers != null) {
5846 mSystemThread.installSystemProviders(providers);
5847 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005848
5849 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005850
5851 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005852 }
5853
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005854 /**
5855 * Allows app to retrieve the MIME type of a URI without having permission
5856 * to access its content provider.
5857 *
5858 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5859 *
5860 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5861 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5862 */
5863 public String getProviderMimeType(Uri uri) {
5864 final String name = uri.getAuthority();
5865 final long ident = Binder.clearCallingIdentity();
5866 ContentProviderHolder holder = null;
5867
5868 try {
5869 holder = getContentProviderExternal(name);
5870 if (holder != null) {
5871 return holder.provider.getType(uri);
5872 }
5873 } catch (RemoteException e) {
5874 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5875 return null;
5876 } finally {
5877 if (holder != null) {
5878 removeContentProviderExternal(name);
5879 }
5880 Binder.restoreCallingIdentity(ident);
5881 }
5882
5883 return null;
5884 }
5885
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005886 // =========================================================
5887 // GLOBAL MANAGEMENT
5888 // =========================================================
5889
5890 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5891 ApplicationInfo info, String customProcess) {
5892 String proc = customProcess != null ? customProcess : info.processName;
5893 BatteryStatsImpl.Uid.Proc ps = null;
5894 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5895 synchronized (stats) {
5896 ps = stats.getProcessStatsLocked(info.uid, proc);
5897 }
5898 return new ProcessRecord(ps, thread, info, proc);
5899 }
5900
5901 final ProcessRecord addAppLocked(ApplicationInfo info) {
5902 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5903
5904 if (app == null) {
5905 app = newProcessRecordLocked(null, info, null);
5906 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005907 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005908 }
5909
Dianne Hackborne7f97212011-02-24 14:40:20 -08005910 // This package really, really can not be stopped.
5911 try {
5912 AppGlobals.getPackageManager().setPackageStoppedState(
5913 info.packageName, false);
5914 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005915 } catch (IllegalArgumentException e) {
5916 Slog.w(TAG, "Failed trying to unstop package "
5917 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005918 }
5919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5921 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5922 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07005923 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005924 }
5925 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5926 mPersistentStartingProcesses.add(app);
5927 startProcessLocked(app, "added application", app.processName);
5928 }
5929
5930 return app;
5931 }
5932
5933 public void unhandledBack() {
5934 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5935 "unhandledBack()");
5936
5937 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005938 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005939 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005940 TAG, "Performing unhandledBack(): stack size = " + count);
5941 if (count > 1) {
5942 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005943 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005944 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5945 Binder.restoreCallingIdentity(origId);
5946 }
5947 }
5948 }
5949
5950 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5951 String name = uri.getAuthority();
5952 ContentProviderHolder cph = getContentProviderExternal(name);
5953 ParcelFileDescriptor pfd = null;
5954 if (cph != null) {
5955 // We record the binder invoker's uid in thread-local storage before
5956 // going to the content provider to open the file. Later, in the code
5957 // that handles all permissions checks, we look for this uid and use
5958 // that rather than the Activity Manager's own uid. The effect is that
5959 // we do the check against the caller's permissions even though it looks
5960 // to the content provider like the Activity Manager itself is making
5961 // the request.
5962 sCallerIdentity.set(new Identity(
5963 Binder.getCallingPid(), Binder.getCallingUid()));
5964 try {
5965 pfd = cph.provider.openFile(uri, "r");
5966 } catch (FileNotFoundException e) {
5967 // do nothing; pfd will be returned null
5968 } finally {
5969 // Ensure that whatever happens, we clean up the identity state
5970 sCallerIdentity.remove();
5971 }
5972
5973 // We've got the fd now, so we're done with the provider.
5974 removeContentProviderExternal(name);
5975 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005976 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005977 }
5978 return pfd;
5979 }
5980
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005981 // Actually is sleeping or shutting down or whatever else in the future
5982 // is an inactive state.
5983 public boolean isSleeping() {
5984 return mSleeping || mShuttingDown;
5985 }
5986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 public void goingToSleep() {
5988 synchronized(this) {
5989 mSleeping = true;
5990 mWindowManager.setEventDispatching(false);
5991
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08005992 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005993
5994 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07005995 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005996 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
5997 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07005998 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005999 }
6000 }
6001
Dianne Hackborn55280a92009-05-07 15:53:46 -07006002 public boolean shutdown(int timeout) {
6003 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6004 != PackageManager.PERMISSION_GRANTED) {
6005 throw new SecurityException("Requires permission "
6006 + android.Manifest.permission.SHUTDOWN);
6007 }
6008
6009 boolean timedout = false;
6010
6011 synchronized(this) {
6012 mShuttingDown = true;
6013 mWindowManager.setEventDispatching(false);
6014
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006015 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006016 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006017 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006018 while (mMainStack.mResumedActivity != null
6019 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006020 long delay = endTime - System.currentTimeMillis();
6021 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006022 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006023 timedout = true;
6024 break;
6025 }
6026 try {
6027 this.wait();
6028 } catch (InterruptedException e) {
6029 }
6030 }
6031 }
6032 }
6033
6034 mUsageStatsService.shutdown();
6035 mBatteryStatsService.shutdown();
6036
6037 return timedout;
6038 }
6039
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006040 public final void activitySlept(IBinder token) {
6041 if (localLOGV) Slog.v(
6042 TAG, "Activity slept: token=" + token);
6043
6044 ActivityRecord r = null;
6045
6046 final long origId = Binder.clearCallingIdentity();
6047
6048 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006049 r = mMainStack.isInStackLocked(token);
6050 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006051 mMainStack.activitySleptLocked(r);
6052 }
6053 }
6054
6055 Binder.restoreCallingIdentity(origId);
6056 }
6057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006058 public void wakingUp() {
6059 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006060 mWindowManager.setEventDispatching(true);
6061 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006062 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006063 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 }
6065 }
6066
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006067 public void stopAppSwitches() {
6068 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6069 != PackageManager.PERMISSION_GRANTED) {
6070 throw new SecurityException("Requires permission "
6071 + android.Manifest.permission.STOP_APP_SWITCHES);
6072 }
6073
6074 synchronized(this) {
6075 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6076 + APP_SWITCH_DELAY_TIME;
6077 mDidAppSwitch = false;
6078 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6079 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6080 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6081 }
6082 }
6083
6084 public void resumeAppSwitches() {
6085 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6086 != PackageManager.PERMISSION_GRANTED) {
6087 throw new SecurityException("Requires permission "
6088 + android.Manifest.permission.STOP_APP_SWITCHES);
6089 }
6090
6091 synchronized(this) {
6092 // Note that we don't execute any pending app switches... we will
6093 // let those wait until either the timeout, or the next start
6094 // activity request.
6095 mAppSwitchesAllowedTime = 0;
6096 }
6097 }
6098
6099 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6100 String name) {
6101 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6102 return true;
6103 }
6104
6105 final int perm = checkComponentPermission(
6106 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006107 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006108 if (perm == PackageManager.PERMISSION_GRANTED) {
6109 return true;
6110 }
6111
Joe Onorato8a9b2202010-02-26 18:56:32 -08006112 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006113 return false;
6114 }
6115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006116 public void setDebugApp(String packageName, boolean waitForDebugger,
6117 boolean persistent) {
6118 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6119 "setDebugApp()");
6120
6121 // Note that this is not really thread safe if there are multiple
6122 // callers into it at the same time, but that's not a situation we
6123 // care about.
6124 if (persistent) {
6125 final ContentResolver resolver = mContext.getContentResolver();
6126 Settings.System.putString(
6127 resolver, Settings.System.DEBUG_APP,
6128 packageName);
6129 Settings.System.putInt(
6130 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6131 waitForDebugger ? 1 : 0);
6132 }
6133
6134 synchronized (this) {
6135 if (!persistent) {
6136 mOrigDebugApp = mDebugApp;
6137 mOrigWaitForDebugger = mWaitForDebugger;
6138 }
6139 mDebugApp = packageName;
6140 mWaitForDebugger = waitForDebugger;
6141 mDebugTransient = !persistent;
6142 if (packageName != null) {
6143 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006144 forceStopPackageLocked(packageName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006145 Binder.restoreCallingIdentity(origId);
6146 }
6147 }
6148 }
6149
6150 public void setAlwaysFinish(boolean enabled) {
6151 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6152 "setAlwaysFinish()");
6153
6154 Settings.System.putInt(
6155 mContext.getContentResolver(),
6156 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6157
6158 synchronized (this) {
6159 mAlwaysFinishActivities = enabled;
6160 }
6161 }
6162
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006163 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006164 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006165 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006166 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006167 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006168 }
6169 }
6170
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006171 public boolean isUserAMonkey() {
6172 // For now the fact that there is a controller implies
6173 // we have a monkey.
6174 synchronized (this) {
6175 return mController != null;
6176 }
6177 }
6178
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006179 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006180 synchronized (this) {
6181 mWatchers.register(watcher);
6182 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006183 }
6184
6185 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006186 synchronized (this) {
6187 mWatchers.unregister(watcher);
6188 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006189 }
6190
Jeff Sharkeya4620792011-05-20 15:29:23 -07006191 public void registerProcessObserver(IProcessObserver observer) {
6192 mProcessObservers.register(observer);
6193 }
6194
6195 public void unregisterProcessObserver(IProcessObserver observer) {
6196 mProcessObservers.unregister(observer);
6197 }
6198
Daniel Sandler69a48172010-06-23 16:29:36 -04006199 public void setImmersive(IBinder token, boolean immersive) {
6200 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006201 ActivityRecord r = mMainStack.isInStackLocked(token);
6202 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006203 throw new IllegalArgumentException();
6204 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006205 r.immersive = immersive;
6206 }
6207 }
6208
6209 public boolean isImmersive(IBinder token) {
6210 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006211 ActivityRecord r = mMainStack.isInStackLocked(token);
6212 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006213 throw new IllegalArgumentException();
6214 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006215 return r.immersive;
6216 }
6217 }
6218
6219 public boolean isTopActivityImmersive() {
6220 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006221 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006222 return (r != null) ? r.immersive : false;
6223 }
6224 }
6225
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006226 public final void enterSafeMode() {
6227 synchronized(this) {
6228 // It only makes sense to do this before the system is ready
6229 // and started launching other packages.
6230 if (!mSystemReady) {
6231 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006232 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006233 } catch (RemoteException e) {
6234 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006235 }
6236 }
6237 }
6238
Jeff Brownb09abc12011-01-13 21:08:27 -08006239 public final void showSafeModeOverlay() {
6240 View v = LayoutInflater.from(mContext).inflate(
6241 com.android.internal.R.layout.safe_mode, null);
6242 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6243 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6244 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6245 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6246 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6247 lp.format = v.getBackground().getOpacity();
6248 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6249 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6250 ((WindowManager)mContext.getSystemService(
6251 Context.WINDOW_SERVICE)).addView(v, lp);
6252 }
6253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006254 public void noteWakeupAlarm(IIntentSender sender) {
6255 if (!(sender instanceof PendingIntentRecord)) {
6256 return;
6257 }
6258 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6259 synchronized (stats) {
6260 if (mBatteryStatsService.isOnBattery()) {
6261 mBatteryStatsService.enforceCallingPermission();
6262 PendingIntentRecord rec = (PendingIntentRecord)sender;
6263 int MY_UID = Binder.getCallingUid();
6264 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6265 BatteryStatsImpl.Uid.Pkg pkg =
6266 stats.getPackageStatsLocked(uid, rec.key.packageName);
6267 pkg.incWakeupsLocked();
6268 }
6269 }
6270 }
6271
Dianne Hackborn64825172011-03-02 21:32:58 -08006272 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006273 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006274 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006276 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 // XXX Note: don't acquire main activity lock here, because the window
6278 // manager calls in with its locks held.
6279
6280 boolean killed = false;
6281 synchronized (mPidsSelfLocked) {
6282 int[] types = new int[pids.length];
6283 int worstType = 0;
6284 for (int i=0; i<pids.length; i++) {
6285 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6286 if (proc != null) {
6287 int type = proc.setAdj;
6288 types[i] = type;
6289 if (type > worstType) {
6290 worstType = type;
6291 }
6292 }
6293 }
6294
Dianne Hackborn64825172011-03-02 21:32:58 -08006295 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006297 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6298 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006299 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006300
6301 // If this is not a secure call, don't let it kill processes that
6302 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006303 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6304 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006305 }
6306
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006307 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006308 for (int i=0; i<pids.length; i++) {
6309 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6310 if (proc == null) {
6311 continue;
6312 }
6313 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006314 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006315 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006316 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6317 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006318 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006319 proc.killedBackground = true;
6320 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006321 }
6322 }
6323 }
6324 return killed;
6325 }
6326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006327 public final void startRunning(String pkg, String cls, String action,
6328 String data) {
6329 synchronized(this) {
6330 if (mStartRunning) {
6331 return;
6332 }
6333 mStartRunning = true;
6334 mTopComponent = pkg != null && cls != null
6335 ? new ComponentName(pkg, cls) : null;
6336 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6337 mTopData = data;
6338 if (!mSystemReady) {
6339 return;
6340 }
6341 }
6342
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006343 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006344 }
6345
6346 private void retrieveSettings() {
6347 final ContentResolver resolver = mContext.getContentResolver();
6348 String debugApp = Settings.System.getString(
6349 resolver, Settings.System.DEBUG_APP);
6350 boolean waitForDebugger = Settings.System.getInt(
6351 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6352 boolean alwaysFinishActivities = Settings.System.getInt(
6353 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6354
6355 Configuration configuration = new Configuration();
6356 Settings.System.getConfiguration(resolver, configuration);
6357
6358 synchronized (this) {
6359 mDebugApp = mOrigDebugApp = debugApp;
6360 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6361 mAlwaysFinishActivities = alwaysFinishActivities;
6362 // This happens before any activities are started, so we can
6363 // change mConfiguration in-place.
6364 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006365 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006366 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006367 }
6368 }
6369
6370 public boolean testIsSystemReady() {
6371 // no need to synchronize(this) just to read & return the value
6372 return mSystemReady;
6373 }
6374
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006375 private static File getCalledPreBootReceiversFile() {
6376 File dataDir = Environment.getDataDirectory();
6377 File systemDir = new File(dataDir, "system");
6378 File fname = new File(systemDir, "called_pre_boots.dat");
6379 return fname;
6380 }
6381
6382 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6383 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6384 File file = getCalledPreBootReceiversFile();
6385 FileInputStream fis = null;
6386 try {
6387 fis = new FileInputStream(file);
6388 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6389 int vers = dis.readInt();
6390 String codename = dis.readUTF();
6391 if (vers == android.os.Build.VERSION.SDK_INT
6392 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6393 int num = dis.readInt();
6394 while (num > 0) {
6395 num--;
6396 String pkg = dis.readUTF();
6397 String cls = dis.readUTF();
6398 lastDoneReceivers.add(new ComponentName(pkg, cls));
6399 }
6400 }
6401 } catch (FileNotFoundException e) {
6402 } catch (IOException e) {
6403 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6404 } finally {
6405 if (fis != null) {
6406 try {
6407 fis.close();
6408 } catch (IOException e) {
6409 }
6410 }
6411 }
6412 return lastDoneReceivers;
6413 }
6414
6415 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6416 File file = getCalledPreBootReceiversFile();
6417 FileOutputStream fos = null;
6418 DataOutputStream dos = null;
6419 try {
6420 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6421 fos = new FileOutputStream(file);
6422 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6423 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6424 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6425 dos.writeInt(list.size());
6426 for (int i=0; i<list.size(); i++) {
6427 dos.writeUTF(list.get(i).getPackageName());
6428 dos.writeUTF(list.get(i).getClassName());
6429 }
6430 } catch (IOException e) {
6431 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6432 file.delete();
6433 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006434 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006435 if (dos != null) {
6436 try {
6437 dos.close();
6438 } catch (IOException e) {
6439 // TODO Auto-generated catch block
6440 e.printStackTrace();
6441 }
6442 }
6443 }
6444 }
6445
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006446 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 synchronized(this) {
6448 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006449 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 return;
6451 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006452
6453 // Check to see if there are any update receivers to run.
6454 if (!mDidUpdate) {
6455 if (mWaitingUpdate) {
6456 return;
6457 }
6458 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6459 List<ResolveInfo> ris = null;
6460 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006461 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006462 intent, null, 0);
6463 } catch (RemoteException e) {
6464 }
6465 if (ris != null) {
6466 for (int i=ris.size()-1; i>=0; i--) {
6467 if ((ris.get(i).activityInfo.applicationInfo.flags
6468 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6469 ris.remove(i);
6470 }
6471 }
6472 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006473
6474 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6475
6476 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006477 for (int i=0; i<ris.size(); i++) {
6478 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006479 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6480 if (lastDoneReceivers.contains(comp)) {
6481 ris.remove(i);
6482 i--;
6483 }
6484 }
6485
6486 for (int i=0; i<ris.size(); i++) {
6487 ActivityInfo ai = ris.get(i).activityInfo;
6488 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6489 doneReceivers.add(comp);
6490 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006491 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006492 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006493 finisher = new IIntentReceiver.Stub() {
6494 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006495 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006496 boolean sticky) {
6497 // The raw IIntentReceiver interface is called
6498 // with the AM lock held, so redispatch to
6499 // execute our code without the lock.
6500 mHandler.post(new Runnable() {
6501 public void run() {
6502 synchronized (ActivityManagerService.this) {
6503 mDidUpdate = true;
6504 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006505 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006506 systemReady(goingCallback);
6507 }
6508 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006509 }
6510 };
6511 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006512 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006513 broadcastIntentLocked(null, null, intent, null, finisher,
6514 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006515 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006516 mWaitingUpdate = true;
6517 }
6518 }
6519 }
6520 if (mWaitingUpdate) {
6521 return;
6522 }
6523 mDidUpdate = true;
6524 }
6525
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006526 mSystemReady = true;
6527 if (!mStartRunning) {
6528 return;
6529 }
6530 }
6531
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006532 ArrayList<ProcessRecord> procsToKill = null;
6533 synchronized(mPidsSelfLocked) {
6534 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6535 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6536 if (!isAllowedWhileBooting(proc.info)){
6537 if (procsToKill == null) {
6538 procsToKill = new ArrayList<ProcessRecord>();
6539 }
6540 procsToKill.add(proc);
6541 }
6542 }
6543 }
6544
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006545 synchronized(this) {
6546 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006547 for (int i=procsToKill.size()-1; i>=0; i--) {
6548 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006549 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006550 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006551 }
6552 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006553
6554 // Now that we have cleaned up any update processes, we
6555 // are ready to start launching real processes and know that
6556 // we won't trample on them any more.
6557 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006558 }
6559
Joe Onorato8a9b2202010-02-26 18:56:32 -08006560 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006561 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006562 SystemClock.uptimeMillis());
6563
6564 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006565 // Make sure we have no pre-ready processes sitting around.
6566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6568 ResolveInfo ri = mContext.getPackageManager()
6569 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006570 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006571 CharSequence errorMsg = null;
6572 if (ri != null) {
6573 ActivityInfo ai = ri.activityInfo;
6574 ApplicationInfo app = ai.applicationInfo;
6575 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6576 mTopAction = Intent.ACTION_FACTORY_TEST;
6577 mTopData = null;
6578 mTopComponent = new ComponentName(app.packageName,
6579 ai.name);
6580 } else {
6581 errorMsg = mContext.getResources().getText(
6582 com.android.internal.R.string.factorytest_not_system);
6583 }
6584 } else {
6585 errorMsg = mContext.getResources().getText(
6586 com.android.internal.R.string.factorytest_no_action);
6587 }
6588 if (errorMsg != null) {
6589 mTopAction = null;
6590 mTopData = null;
6591 mTopComponent = null;
6592 Message msg = Message.obtain();
6593 msg.what = SHOW_FACTORY_ERROR_MSG;
6594 msg.getData().putCharSequence("msg", errorMsg);
6595 mHandler.sendMessage(msg);
6596 }
6597 }
6598 }
6599
6600 retrieveSettings();
6601
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006602 if (goingCallback != null) goingCallback.run();
6603
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006604 synchronized (this) {
6605 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6606 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006607 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006608 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006609 if (apps != null) {
6610 int N = apps.size();
6611 int i;
6612 for (i=0; i<N; i++) {
6613 ApplicationInfo info
6614 = (ApplicationInfo)apps.get(i);
6615 if (info != null &&
6616 !info.packageName.equals("android")) {
6617 addAppLocked(info);
6618 }
6619 }
6620 }
6621 } catch (RemoteException ex) {
6622 // pm is in same process, this will never happen.
6623 }
6624 }
6625
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006626 // Start up initial activity.
6627 mBooting = true;
6628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006629 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006630 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 Message msg = Message.obtain();
6632 msg.what = SHOW_UID_ERROR_MSG;
6633 mHandler.sendMessage(msg);
6634 }
6635 } catch (RemoteException e) {
6636 }
6637
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006638 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006639 }
6640 }
6641
Dan Egnorb7f03672009-12-09 16:22:32 -08006642 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006643 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006645 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006646 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006647 startAppProblemLocked(app);
6648 app.stopFreezingAllLocked();
6649 return handleAppCrashLocked(app);
6650 }
6651
Dan Egnorb7f03672009-12-09 16:22:32 -08006652 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006653 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006654 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006655 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006656 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6657 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006658 startAppProblemLocked(app);
6659 app.stopFreezingAllLocked();
6660 }
6661
6662 /**
6663 * Generate a process error record, suitable for attachment to a ProcessRecord.
6664 *
6665 * @param app The ProcessRecord in which the error occurred.
6666 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6667 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006668 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 * @param shortMsg Short message describing the crash.
6670 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006671 * @param stackTrace Full crash stack trace, may be null.
6672 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006673 * @return Returns a fully-formed AppErrorStateInfo record.
6674 */
6675 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006676 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006677 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006679 report.condition = condition;
6680 report.processName = app.processName;
6681 report.pid = app.pid;
6682 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006683 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006684 report.shortMsg = shortMsg;
6685 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006686 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006687
6688 return report;
6689 }
6690
Dan Egnor42471dd2010-01-07 17:25:22 -08006691 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006692 synchronized (this) {
6693 app.crashing = false;
6694 app.crashingReport = null;
6695 app.notResponding = false;
6696 app.notRespondingReport = null;
6697 if (app.anrDialog == fromDialog) {
6698 app.anrDialog = null;
6699 }
6700 if (app.waitDialog == fromDialog) {
6701 app.waitDialog = null;
6702 }
6703 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006704 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006705 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006706 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6707 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006708 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006709 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006710 }
6711 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006712
Dan Egnorb7f03672009-12-09 16:22:32 -08006713 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006714 long now = SystemClock.uptimeMillis();
6715
6716 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6717 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006718 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006719 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006720 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006721 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006722 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006723 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006724 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6725 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006726 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006727 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006728 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006729 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006730 }
6731 }
6732 if (!app.persistent) {
6733 // We don't want to start this process again until the user
6734 // explicitly does so... but for persistent process, we really
6735 // need to keep it running. If a persistent process is actually
6736 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006737 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006738 app.info.processName);
6739 mBadProcesses.put(app.info.processName, app.info.uid, now);
6740 app.bad = true;
6741 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6742 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006743 // Don't let services in this process be restarted and potentially
6744 // annoy the user repeatedly. Unless it is persistent, since those
6745 // processes run critical code.
6746 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006747 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006748 return false;
6749 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006750 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006751 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006752 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006753 if (r.app == app) {
6754 // If the top running activity is from this crashing
6755 // process, then terminate it to avoid getting in a loop.
6756 Slog.w(TAG, " Force finishing activity "
6757 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006758 int index = mMainStack.indexOfTokenLocked(r);
6759 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006760 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006761 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006762 // stopped, to avoid a situation where one will get
6763 // re-start our crashing activity once it gets resumed again.
6764 index--;
6765 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006766 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006767 if (r.state == ActivityState.RESUMED
6768 || r.state == ActivityState.PAUSING
6769 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006770 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006771 Slog.w(TAG, " Force finishing activity "
6772 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006773 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006774 Activity.RESULT_CANCELED, null, "crashed");
6775 }
6776 }
6777 }
6778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779 }
6780
6781 // Bump up the crash count of any services currently running in the proc.
6782 if (app.services.size() != 0) {
6783 // Any services running in the application need to be placed
6784 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006785 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006786 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006787 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006788 sr.crashCount++;
6789 }
6790 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006791
6792 // If the crashing process is what we consider to be the "home process" and it has been
6793 // replaced by a third-party app, clear the package preferred activities from packages
6794 // with a home activity running in the process to prevent a repeatedly crashing app
6795 // from blocking the user to manually clear the list.
6796 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6797 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6798 Iterator it = mHomeProcess.activities.iterator();
6799 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006800 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006801 if (r.isHomeActivity) {
6802 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6803 try {
6804 ActivityThread.getPackageManager()
6805 .clearPackagePreferredActivities(r.packageName);
6806 } catch (RemoteException c) {
6807 // pm is in same process, this will never happen.
6808 }
6809 }
6810 }
6811 }
6812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006813 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6814 return true;
6815 }
6816
6817 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006818 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6819 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006820 skipCurrentReceiverLocked(app);
6821 }
6822
6823 void skipCurrentReceiverLocked(ProcessRecord app) {
6824 boolean reschedule = false;
6825 BroadcastRecord r = app.curReceiver;
6826 if (r != null) {
6827 // The current broadcast is waiting for this app's receiver
6828 // to be finished. Looks like that's not going to happen, so
6829 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006830 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006831 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6832 r.resultExtras, r.resultAbort, true);
6833 reschedule = true;
6834 }
6835 r = mPendingBroadcast;
6836 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006837 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006838 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006839 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006840 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6841 r.resultExtras, r.resultAbort, true);
6842 reschedule = true;
6843 }
6844 if (reschedule) {
6845 scheduleBroadcastsLocked();
6846 }
6847 }
6848
Dan Egnor60d87622009-12-16 16:32:58 -08006849 /**
6850 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6851 * The application process will exit immediately after this call returns.
6852 * @param app object of the crashing app, null for the system server
6853 * @param crashInfo describing the exception
6854 */
6855 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006856 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006857
6858 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6859 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006860 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006861 crashInfo.exceptionClassName,
6862 crashInfo.exceptionMessage,
6863 crashInfo.throwFileName,
6864 crashInfo.throwLineNumber);
6865
Dan Egnor42471dd2010-01-07 17:25:22 -08006866 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006867
6868 crashApplication(r, crashInfo);
6869 }
6870
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006871 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006872 IBinder app,
6873 int violationMask,
6874 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006875 ProcessRecord r = findAppProcess(app, "StrictMode");
6876 if (r == null) {
6877 return;
6878 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006879
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006880 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006881 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006882 boolean logIt = true;
6883 synchronized (mAlreadyLoggedViolatedStacks) {
6884 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6885 logIt = false;
6886 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006887 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006888 // the relative pain numbers, without logging all
6889 // the stack traces repeatedly. We'd want to do
6890 // likewise in the client code, which also does
6891 // dup suppression, before the Binder call.
6892 } else {
6893 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6894 mAlreadyLoggedViolatedStacks.clear();
6895 }
6896 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6897 }
6898 }
6899 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006900 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006901 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006902 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006903
6904 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6905 AppErrorResult result = new AppErrorResult();
6906 synchronized (this) {
6907 final long origId = Binder.clearCallingIdentity();
6908
6909 Message msg = Message.obtain();
6910 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6911 HashMap<String, Object> data = new HashMap<String, Object>();
6912 data.put("result", result);
6913 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006914 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006915 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006916 msg.obj = data;
6917 mHandler.sendMessage(msg);
6918
6919 Binder.restoreCallingIdentity(origId);
6920 }
6921 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006922 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006923 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006924 }
6925
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006926 // Depending on the policy in effect, there could be a bunch of
6927 // these in quick succession so we try to batch these together to
6928 // minimize disk writes, number of dropbox entries, and maximize
6929 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006930 private void logStrictModeViolationToDropBox(
6931 ProcessRecord process,
6932 StrictMode.ViolationInfo info) {
6933 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006934 return;
6935 }
6936 final boolean isSystemApp = process == null ||
6937 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
6938 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
6939 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
6940 final DropBoxManager dbox = (DropBoxManager)
6941 mContext.getSystemService(Context.DROPBOX_SERVICE);
6942
6943 // Exit early if the dropbox isn't configured to accept this report type.
6944 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
6945
6946 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006947 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006948 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
6949 synchronized (sb) {
6950 bufferWasEmpty = sb.length() == 0;
6951 appendDropBoxProcessHeaders(process, sb);
6952 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
6953 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006954 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
6955 if (info.violationNumThisLoop != 0) {
6956 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
6957 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07006958 if (info.numAnimationsRunning != 0) {
6959 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
6960 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07006961 if (info.broadcastIntentAction != null) {
6962 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
6963 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006964 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006965 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006966 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08006967 if (info.numInstances != -1) {
6968 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
6969 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08006970 if (info.tags != null) {
6971 for (String tag : info.tags) {
6972 sb.append("Span-Tag: ").append(tag).append("\n");
6973 }
6974 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006975 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006976 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
6977 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006978 }
6979 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006980
6981 // Only buffer up to ~64k. Various logging bits truncate
6982 // things at 128k.
6983 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006984 }
6985
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006986 // Flush immediately if the buffer's grown too large, or this
6987 // is a non-system app. Non-system apps are isolated with a
6988 // different tag & policy and not batched.
6989 //
6990 // Batching is useful during internal testing with
6991 // StrictMode settings turned up high. Without batching,
6992 // thousands of separate files could be created on boot.
6993 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006994 new Thread("Error dump: " + dropboxTag) {
6995 @Override
6996 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07006997 String report;
6998 synchronized (sb) {
6999 report = sb.toString();
7000 sb.delete(0, sb.length());
7001 sb.trimToSize();
7002 }
7003 if (report.length() != 0) {
7004 dbox.addText(dropboxTag, report);
7005 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007006 }
7007 }.start();
7008 return;
7009 }
7010
7011 // System app batching:
7012 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007013 // An existing dropbox-writing thread is outstanding, so
7014 // we don't need to start it up. The existing thread will
7015 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007016 return;
7017 }
7018
7019 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7020 // (After this point, we shouldn't access AMS internal data structures.)
7021 new Thread("Error dump: " + dropboxTag) {
7022 @Override
7023 public void run() {
7024 // 5 second sleep to let stacks arrive and be batched together
7025 try {
7026 Thread.sleep(5000); // 5 seconds
7027 } catch (InterruptedException e) {}
7028
7029 String errorReport;
7030 synchronized (mStrictModeBuffer) {
7031 errorReport = mStrictModeBuffer.toString();
7032 if (errorReport.length() == 0) {
7033 return;
7034 }
7035 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7036 mStrictModeBuffer.trimToSize();
7037 }
7038 dbox.addText(dropboxTag, errorReport);
7039 }
7040 }.start();
7041 }
7042
Dan Egnor60d87622009-12-16 16:32:58 -08007043 /**
7044 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7045 * @param app object of the crashing app, null for the system server
7046 * @param tag reported by the caller
7047 * @param crashInfo describing the context of the error
7048 * @return true if the process should exit immediately (WTF is fatal)
7049 */
7050 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007051 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007052 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007053
7054 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7055 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007056 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007057 tag, crashInfo.exceptionMessage);
7058
Dan Egnor42471dd2010-01-07 17:25:22 -08007059 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007060
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007061 if (r != null && r.pid != Process.myPid() &&
7062 Settings.Secure.getInt(mContext.getContentResolver(),
7063 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007064 crashApplication(r, crashInfo);
7065 return true;
7066 } else {
7067 return false;
7068 }
7069 }
7070
7071 /**
7072 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7073 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7074 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007075 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007076 if (app == null) {
7077 return null;
7078 }
7079
7080 synchronized (this) {
7081 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7082 final int NA = apps.size();
7083 for (int ia=0; ia<NA; ia++) {
7084 ProcessRecord p = apps.valueAt(ia);
7085 if (p.thread != null && p.thread.asBinder() == app) {
7086 return p;
7087 }
7088 }
7089 }
7090
Dianne Hackborncb44d962011-03-10 17:02:27 -08007091 Slog.w(TAG, "Can't find mystery application for " + reason
7092 + " from pid=" + Binder.getCallingPid()
7093 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007094 return null;
7095 }
7096 }
7097
7098 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007099 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7100 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007101 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007102 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007103 // Watchdog thread ends up invoking this function (with
7104 // a null ProcessRecord) to add the stack file to dropbox.
7105 // Do not acquire a lock on this (am) in such cases, as it
7106 // could cause a potential deadlock, if and when watchdog
7107 // is invoked due to unavailability of lock on am and it
7108 // would prevent watchdog from killing system_server.
7109 if (process == null) {
7110 sb.append("Process: system_server\n");
7111 return;
7112 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007113 // Note: ProcessRecord 'process' is guarded by the service
7114 // instance. (notably process.pkgList, which could otherwise change
7115 // concurrently during execution of this method)
7116 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007117 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007118 sb.append("Process: system_server\n");
7119 } else {
7120 sb.append("Process: ").append(process.processName).append("\n");
7121 }
Dan Egnora455d192010-03-12 08:52:28 -08007122 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007123 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007124 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7125 for (String pkg : process.pkgList) {
7126 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007127 try {
Dan Egnora455d192010-03-12 08:52:28 -08007128 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7129 if (pi != null) {
7130 sb.append(" v").append(pi.versionCode);
7131 if (pi.versionName != null) {
7132 sb.append(" (").append(pi.versionName).append(")");
7133 }
7134 }
7135 } catch (RemoteException e) {
7136 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007137 }
Dan Egnora455d192010-03-12 08:52:28 -08007138 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007139 }
Dan Egnora455d192010-03-12 08:52:28 -08007140 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007141 }
7142
7143 private static String processClass(ProcessRecord process) {
7144 if (process == null || process.pid == MY_PID) {
7145 return "system_server";
7146 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7147 return "system_app";
7148 } else {
7149 return "data_app";
7150 }
7151 }
7152
7153 /**
7154 * Write a description of an error (crash, WTF, ANR) to the drop box.
7155 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7156 * @param process which caused the error, null means the system server
7157 * @param activity which triggered the error, null if unknown
7158 * @param parent activity related to the error, null if unknown
7159 * @param subject line related to the error, null if absent
7160 * @param report in long form describing the error, null if absent
7161 * @param logFile to include in the report, null if none
7162 * @param crashInfo giving an application stack trace, null if absent
7163 */
7164 public void addErrorToDropBox(String eventType,
7165 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7166 final String report, final File logFile,
7167 final ApplicationErrorReport.CrashInfo crashInfo) {
7168 // NOTE -- this must never acquire the ActivityManagerService lock,
7169 // otherwise the watchdog may be prevented from resetting the system.
7170
7171 final String dropboxTag = processClass(process) + "_" + eventType;
7172 final DropBoxManager dbox = (DropBoxManager)
7173 mContext.getSystemService(Context.DROPBOX_SERVICE);
7174
7175 // Exit early if the dropbox isn't configured to accept this report type.
7176 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7177
7178 final StringBuilder sb = new StringBuilder(1024);
7179 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007180 if (activity != null) {
7181 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7182 }
7183 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7184 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7185 }
7186 if (parent != null && parent != activity) {
7187 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7188 }
7189 if (subject != null) {
7190 sb.append("Subject: ").append(subject).append("\n");
7191 }
7192 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007193 if (Debug.isDebuggerConnected()) {
7194 sb.append("Debugger: Connected\n");
7195 }
Dan Egnora455d192010-03-12 08:52:28 -08007196 sb.append("\n");
7197
7198 // Do the rest in a worker thread to avoid blocking the caller on I/O
7199 // (After this point, we shouldn't access AMS internal data structures.)
7200 Thread worker = new Thread("Error dump: " + dropboxTag) {
7201 @Override
7202 public void run() {
7203 if (report != null) {
7204 sb.append(report);
7205 }
7206 if (logFile != null) {
7207 try {
7208 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7209 } catch (IOException e) {
7210 Slog.e(TAG, "Error reading " + logFile, e);
7211 }
7212 }
7213 if (crashInfo != null && crashInfo.stackTrace != null) {
7214 sb.append(crashInfo.stackTrace);
7215 }
7216
7217 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7218 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7219 if (lines > 0) {
7220 sb.append("\n");
7221
7222 // Merge several logcat streams, and take the last N lines
7223 InputStreamReader input = null;
7224 try {
7225 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7226 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7227 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7228
7229 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7230 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7231 input = new InputStreamReader(logcat.getInputStream());
7232
7233 int num;
7234 char[] buf = new char[8192];
7235 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7236 } catch (IOException e) {
7237 Slog.e(TAG, "Error running logcat", e);
7238 } finally {
7239 if (input != null) try { input.close(); } catch (IOException e) {}
7240 }
7241 }
7242
7243 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007244 }
Dan Egnora455d192010-03-12 08:52:28 -08007245 };
7246
7247 if (process == null || process.pid == MY_PID) {
7248 worker.run(); // We may be about to die -- need to run this synchronously
7249 } else {
7250 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007251 }
7252 }
7253
7254 /**
7255 * Bring up the "unexpected error" dialog box for a crashing app.
7256 * Deal with edge cases (intercepts from instrumented applications,
7257 * ActivityController, error intent receivers, that sort of thing).
7258 * @param r the application crashing
7259 * @param crashInfo describing the failure
7260 */
7261 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007262 long timeMillis = System.currentTimeMillis();
7263 String shortMsg = crashInfo.exceptionClassName;
7264 String longMsg = crashInfo.exceptionMessage;
7265 String stackTrace = crashInfo.stackTrace;
7266 if (shortMsg != null && longMsg != null) {
7267 longMsg = shortMsg + ": " + longMsg;
7268 } else if (shortMsg != null) {
7269 longMsg = shortMsg;
7270 }
7271
Dan Egnor60d87622009-12-16 16:32:58 -08007272 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007274 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007275 try {
7276 String name = r != null ? r.processName : null;
7277 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007278 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007279 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007280 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007281 + " at watcher's request");
7282 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007283 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007284 }
7285 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007286 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 }
7288 }
7289
7290 final long origId = Binder.clearCallingIdentity();
7291
7292 // If this process is running instrumentation, finish it.
7293 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007294 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007295 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007296 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7297 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007298 Bundle info = new Bundle();
7299 info.putString("shortMsg", shortMsg);
7300 info.putString("longMsg", longMsg);
7301 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7302 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007303 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007304 }
7305
Dan Egnor60d87622009-12-16 16:32:58 -08007306 // If we can't identify the process or it's already exceeded its crash quota,
7307 // quit right away without showing a crash dialog.
7308 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007309 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007310 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007311 }
7312
7313 Message msg = Message.obtain();
7314 msg.what = SHOW_ERROR_MSG;
7315 HashMap data = new HashMap();
7316 data.put("result", result);
7317 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007318 msg.obj = data;
7319 mHandler.sendMessage(msg);
7320
7321 Binder.restoreCallingIdentity(origId);
7322 }
7323
7324 int res = result.get();
7325
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007326 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007327 synchronized (this) {
7328 if (r != null) {
7329 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7330 SystemClock.uptimeMillis());
7331 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007332 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007333 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007334 }
7335 }
7336
7337 if (appErrorIntent != null) {
7338 try {
7339 mContext.startActivity(appErrorIntent);
7340 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007341 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007345
7346 Intent createAppErrorIntentLocked(ProcessRecord r,
7347 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7348 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007349 if (report == null) {
7350 return null;
7351 }
7352 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7353 result.setComponent(r.errorReportReceiver);
7354 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7355 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7356 return result;
7357 }
7358
Dan Egnorb7f03672009-12-09 16:22:32 -08007359 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7360 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007361 if (r.errorReportReceiver == null) {
7362 return null;
7363 }
7364
7365 if (!r.crashing && !r.notResponding) {
7366 return null;
7367 }
7368
Dan Egnorb7f03672009-12-09 16:22:32 -08007369 ApplicationErrorReport report = new ApplicationErrorReport();
7370 report.packageName = r.info.packageName;
7371 report.installerPackageName = r.errorReportReceiver.getPackageName();
7372 report.processName = r.processName;
7373 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007374 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007375
Dan Egnorb7f03672009-12-09 16:22:32 -08007376 if (r.crashing) {
7377 report.type = ApplicationErrorReport.TYPE_CRASH;
7378 report.crashInfo = crashInfo;
7379 } else if (r.notResponding) {
7380 report.type = ApplicationErrorReport.TYPE_ANR;
7381 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007382
Dan Egnorb7f03672009-12-09 16:22:32 -08007383 report.anrInfo.activity = r.notRespondingReport.tag;
7384 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7385 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007386 }
7387
Dan Egnorb7f03672009-12-09 16:22:32 -08007388 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007389 }
7390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007391 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7392 // assume our apps are happy - lazy create the list
7393 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7394
7395 synchronized (this) {
7396
7397 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007398 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7399 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007400 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7401 // This one's in trouble, so we'll generate a report for it
7402 // crashes are higher priority (in case there's a crash *and* an anr)
7403 ActivityManager.ProcessErrorStateInfo report = null;
7404 if (app.crashing) {
7405 report = app.crashingReport;
7406 } else if (app.notResponding) {
7407 report = app.notRespondingReport;
7408 }
7409
7410 if (report != null) {
7411 if (errList == null) {
7412 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7413 }
7414 errList.add(report);
7415 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007416 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007417 " crashing = " + app.crashing +
7418 " notResponding = " + app.notResponding);
7419 }
7420 }
7421 }
7422 }
7423
7424 return errList;
7425 }
7426
7427 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7428 // Lazy instantiation of list
7429 List<ActivityManager.RunningAppProcessInfo> runList = null;
7430 synchronized (this) {
7431 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007432 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7433 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7435 // Generate process state info for running application
7436 ActivityManager.RunningAppProcessInfo currApp =
7437 new ActivityManager.RunningAppProcessInfo(app.processName,
7438 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007439 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007440 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007441 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007442 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007443 if (app.persistent) {
7444 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007446 int adj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007447 if (adj >= ProcessList.EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007448 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007449 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007450 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007451 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7452 } else if (adj >= ProcessList.HOME_APP_ADJ) {
The Android Open Source Project4df24232009-03-05 14:34:35 -08007453 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7454 currApp.lru = 0;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007455 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007456 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007457 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007458 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007459 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007460 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007461 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007462 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7463 } else {
7464 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7465 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007466 currApp.importanceReasonCode = app.adjTypeCode;
7467 if (app.adjSource instanceof ProcessRecord) {
7468 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007469 } else if (app.adjSource instanceof ActivityRecord) {
7470 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007471 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7472 }
7473 if (app.adjTarget instanceof ComponentName) {
7474 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7475 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007476 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007477 // + " lru=" + currApp.lru);
7478 if (runList == null) {
7479 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7480 }
7481 runList.add(currApp);
7482 }
7483 }
7484 }
7485 return runList;
7486 }
7487
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007488 public List<ApplicationInfo> getRunningExternalApplications() {
7489 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7490 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7491 if (runningApps != null && runningApps.size() > 0) {
7492 Set<String> extList = new HashSet<String>();
7493 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7494 if (app.pkgList != null) {
7495 for (String pkg : app.pkgList) {
7496 extList.add(pkg);
7497 }
7498 }
7499 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007500 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007501 for (String pkg : extList) {
7502 try {
7503 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7504 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7505 retList.add(info);
7506 }
7507 } catch (RemoteException e) {
7508 }
7509 }
7510 }
7511 return retList;
7512 }
7513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007514 @Override
7515 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007516 if (checkCallingPermission(android.Manifest.permission.DUMP)
7517 != PackageManager.PERMISSION_GRANTED) {
7518 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7519 + Binder.getCallingPid()
7520 + ", uid=" + Binder.getCallingUid()
7521 + " without permission "
7522 + android.Manifest.permission.DUMP);
7523 return;
7524 }
7525
7526 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007527 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007528
7529 int opti = 0;
7530 while (opti < args.length) {
7531 String opt = args[opti];
7532 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7533 break;
7534 }
7535 opti++;
7536 if ("-a".equals(opt)) {
7537 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007538 } else if ("-c".equals(opt)) {
7539 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007540 } else if ("-h".equals(opt)) {
7541 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007542 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007543 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007544 pw.println(" a[ctivities]: activity stack state");
7545 pw.println(" b[roadcasts]: broadcast state");
7546 pw.println(" i[ntents]: pending intent state");
7547 pw.println(" p[rocesses]: process state");
7548 pw.println(" o[om]: out of memory management");
7549 pw.println(" prov[iders]: content provider state");
7550 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007551 pw.println(" service [COMP_SPEC]: service client-side state");
7552 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7553 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7554 pw.println(" a partial substring in a component name, an");
7555 pw.println(" ActivityRecord hex object identifier, or");
Dianne Hackbornf9302322011-06-14 18:36:14 -07007556 pw.println(" \"all\" for all objects, or");
7557 pw.println(" \"top\" for the top activity.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007558 pw.println(" -a: include all available server state.");
7559 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007560 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007561 } else {
7562 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007563 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007564 }
7565
7566 // Is the caller requesting to dump a particular piece of data?
7567 if (opti < args.length) {
7568 String cmd = args[opti];
7569 opti++;
7570 if ("activities".equals(cmd) || "a".equals(cmd)) {
7571 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007572 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007573 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007574 return;
7575 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7576 synchronized (this) {
7577 dumpBroadcastsLocked(fd, pw, args, opti, true);
7578 }
7579 return;
7580 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7581 synchronized (this) {
7582 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7583 }
7584 return;
7585 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7586 synchronized (this) {
7587 dumpProcessesLocked(fd, pw, args, opti, true);
7588 }
7589 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007590 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7591 synchronized (this) {
7592 dumpOomLocked(fd, pw, args, opti, true);
7593 }
7594 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007595 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7596 synchronized (this) {
7597 dumpProvidersLocked(fd, pw, args, opti, true);
7598 }
7599 return;
7600 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007601 String[] newArgs;
7602 String name;
7603 if (opti >= args.length) {
7604 name = null;
7605 newArgs = EMPTY_STRING_ARRAY;
7606 } else {
7607 name = args[opti];
7608 opti++;
7609 newArgs = new String[args.length - opti];
7610 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7611 }
7612 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7613 pw.println("No services match: " + name);
7614 pw.println("Use -h for help.");
7615 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007616 return;
7617 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7618 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007619 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007620 }
7621 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007622 } else {
7623 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007624 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7625 pw.println("Bad activity command, or no activities match: " + cmd);
7626 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007627 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007628 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007630 }
7631
7632 // No piece of data specified, dump everything.
7633 synchronized (this) {
7634 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007635 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007636 if (needSep) {
7637 pw.println(" ");
7638 }
7639 if (dumpAll) {
7640 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007641 }
7642 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7643 if (needSep) {
7644 pw.println(" ");
7645 }
7646 if (dumpAll) {
7647 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007648 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007649 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007650 if (needSep) {
7651 pw.println(" ");
7652 }
7653 if (dumpAll) {
7654 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007655 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007656 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007657 if (needSep) {
7658 pw.println(" ");
7659 }
7660 if (dumpAll) {
7661 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007662 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007663 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007664 if (needSep) {
7665 pw.println(" ");
7666 }
7667 if (dumpAll) {
7668 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007669 }
7670 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7671 }
7672 }
7673
7674 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007675 int opti, boolean dumpAll, boolean dumpClient) {
7676 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7677 pw.println(" Main stack:");
7678 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007679 pw.println(" ");
7680 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007681 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007682 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007683 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007684 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007685 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7686 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007687 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007688 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007689 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007690 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007691 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7692 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007693 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007694 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7695 pw.println(" ");
7696 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007697 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7698 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007699 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007700 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007701 pw.println(" ");
7702 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007703 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7704 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007705 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007706
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007707 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007708 if (mMainStack.mPausingActivity != null) {
7709 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7710 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007711 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007712 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007713 if (dumpAll) {
7714 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7715 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7716 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007717
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007718 if (mRecentTasks.size() > 0) {
7719 pw.println();
7720 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007721
7722 final int N = mRecentTasks.size();
7723 for (int i=0; i<N; i++) {
7724 TaskRecord tr = mRecentTasks.get(i);
7725 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7726 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007727 if (dumpAll) {
7728 mRecentTasks.get(i).dump(pw, " ");
7729 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007730 }
7731 }
7732
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007733 if (dumpAll) {
7734 pw.println(" ");
7735 pw.println(" mCurTask: " + mCurTask);
7736 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007737
7738 return true;
7739 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007740
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007741 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7742 int opti, boolean dumpAll) {
7743 boolean needSep = false;
7744 int numPers = 0;
7745
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007746 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7747
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007748 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007749 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7750 final int NA = procs.size();
7751 for (int ia=0; ia<NA; ia++) {
7752 if (!needSep) {
7753 pw.println(" All known processes:");
7754 needSep = true;
7755 }
7756 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007757 pw.print(r.persistent ? " *PERS*" : " *APP*");
7758 pw.print(" UID "); pw.print(procs.keyAt(ia));
7759 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007760 r.dump(pw, " ");
7761 if (r.persistent) {
7762 numPers++;
7763 }
7764 }
7765 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007766 }
7767
7768 if (mLruProcesses.size() > 0) {
7769 if (needSep) pw.println(" ");
7770 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007771 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007772 dumpProcessOomList(pw, this, mLruProcesses, " ",
7773 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007774 needSep = true;
7775 }
7776
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007777 if (dumpAll) {
7778 synchronized (mPidsSelfLocked) {
7779 if (mPidsSelfLocked.size() > 0) {
7780 if (needSep) pw.println(" ");
7781 needSep = true;
7782 pw.println(" PID mappings:");
7783 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7784 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7785 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7786 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007787 }
7788 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007789 }
7790
7791 if (mForegroundProcesses.size() > 0) {
7792 if (needSep) pw.println(" ");
7793 needSep = true;
7794 pw.println(" Foreground Processes:");
7795 for (int i=0; i<mForegroundProcesses.size(); i++) {
7796 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7797 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007798 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007799 }
7800
7801 if (mPersistentStartingProcesses.size() > 0) {
7802 if (needSep) pw.println(" ");
7803 needSep = true;
7804 pw.println(" Persisent processes that are starting:");
7805 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007806 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007809 if (mRemovedProcesses.size() > 0) {
7810 if (needSep) pw.println(" ");
7811 needSep = true;
7812 pw.println(" Processes that are being removed:");
7813 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007814 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007815 }
7816
7817 if (mProcessesOnHold.size() > 0) {
7818 if (needSep) pw.println(" ");
7819 needSep = true;
7820 pw.println(" Processes that are on old until the system is ready:");
7821 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007822 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007824
Dianne Hackborn287952c2010-09-22 22:34:31 -07007825 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007826
7827 if (mProcessCrashTimes.getMap().size() > 0) {
7828 if (needSep) pw.println(" ");
7829 needSep = true;
7830 pw.println(" Time since processes crashed:");
7831 long now = SystemClock.uptimeMillis();
7832 for (Map.Entry<String, SparseArray<Long>> procs
7833 : mProcessCrashTimes.getMap().entrySet()) {
7834 SparseArray<Long> uids = procs.getValue();
7835 final int N = uids.size();
7836 for (int i=0; i<N; i++) {
7837 pw.print(" Process "); pw.print(procs.getKey());
7838 pw.print(" uid "); pw.print(uids.keyAt(i));
7839 pw.print(": last crashed ");
7840 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007841 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007842 }
7843 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007845
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007846 if (mBadProcesses.getMap().size() > 0) {
7847 if (needSep) pw.println(" ");
7848 needSep = true;
7849 pw.println(" Bad processes:");
7850 for (Map.Entry<String, SparseArray<Long>> procs
7851 : mBadProcesses.getMap().entrySet()) {
7852 SparseArray<Long> uids = procs.getValue();
7853 final int N = uids.size();
7854 for (int i=0; i<N; i++) {
7855 pw.print(" Bad process "); pw.print(procs.getKey());
7856 pw.print(" uid "); pw.print(uids.keyAt(i));
7857 pw.print(": crashed at time ");
7858 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007859 }
7860 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007861 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007862
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007863 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007864 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007865 if (mHeavyWeightProcess != null) {
7866 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7867 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007868 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007869 if (dumpAll) {
7870 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007871 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007872 pw.println(" mScreenCompatPackages:");
7873 for (Map.Entry<String, Integer> entry
7874 : mCompatModePackages.getPackages().entrySet()) {
7875 String pkg = entry.getKey();
7876 int mode = entry.getValue();
7877 pw.print(" "); pw.print(pkg); pw.print(": ");
7878 pw.print(mode); pw.println();
7879 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007880 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007881 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007882 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7883 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7884 || mOrigWaitForDebugger) {
7885 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7886 + " mDebugTransient=" + mDebugTransient
7887 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7888 }
7889 if (mAlwaysFinishActivities || mController != null) {
7890 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7891 + " mController=" + mController);
7892 }
7893 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007895 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007896 + " mProcessesReady=" + mProcessesReady
7897 + " mSystemReady=" + mSystemReady);
7898 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007899 + " mBooted=" + mBooted
7900 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007901 pw.print(" mLastPowerCheckRealtime=");
7902 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7903 pw.println("");
7904 pw.print(" mLastPowerCheckUptime=");
7905 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7906 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007907 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7908 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007909 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007910 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007911
7912 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007913 }
7914
Dianne Hackborn287952c2010-09-22 22:34:31 -07007915 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7916 int opti, boolean needSep, boolean dumpAll) {
7917 if (mProcessesToGc.size() > 0) {
7918 if (needSep) pw.println(" ");
7919 needSep = true;
7920 pw.println(" Processes that are waiting to GC:");
7921 long now = SystemClock.uptimeMillis();
7922 for (int i=0; i<mProcessesToGc.size(); i++) {
7923 ProcessRecord proc = mProcessesToGc.get(i);
7924 pw.print(" Process "); pw.println(proc);
7925 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7926 pw.print(", last gced=");
7927 pw.print(now-proc.lastRequestedGc);
7928 pw.print(" ms ago, last lowMem=");
7929 pw.print(now-proc.lastLowMemory);
7930 pw.println(" ms ago");
7931
7932 }
7933 }
7934 return needSep;
7935 }
7936
7937 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7938 int opti, boolean dumpAll) {
7939 boolean needSep = false;
7940
7941 if (mLruProcesses.size() > 0) {
7942 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
7943
7944 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
7945 @Override
7946 public int compare(ProcessRecord object1, ProcessRecord object2) {
7947 if (object1.setAdj != object2.setAdj) {
7948 return object1.setAdj > object2.setAdj ? -1 : 1;
7949 }
7950 if (object1.setSchedGroup != object2.setSchedGroup) {
7951 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
7952 }
7953 if (object1.keeping != object2.keeping) {
7954 return object1.keeping ? -1 : 1;
7955 }
7956 if (object1.pid != object2.pid) {
7957 return object1.pid > object2.pid ? -1 : 1;
7958 }
7959 return 0;
7960 }
7961 };
7962
7963 Collections.sort(procs, comparator);
7964
7965 if (needSep) pw.println(" ");
7966 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07007967 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07007968 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
7969 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
7970 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
7971 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
7972 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
7973 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
7974 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
7975 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
7976 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
7977 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
7978 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07007979
7980 if (needSep) pw.println(" ");
7981 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007982 pw.println(" Process OOM control:");
7983 dumpProcessOomList(pw, this, procs, " ",
7984 "Proc", "PERS", true);
7985 needSep = true;
7986 }
7987
7988 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
7989
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007990 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07007991 pw.println(" mHomeProcess: " + mHomeProcess);
7992 if (mHeavyWeightProcess != null) {
7993 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7994 }
7995
7996 return true;
7997 }
7998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007999 /**
8000 * There are three ways to call this:
8001 * - no service specified: dump all the services
8002 * - a flattened component name that matched an existing service was specified as the
8003 * first arg: dump that one service
8004 * - the first arg isn't the flattened component name of an existing service:
8005 * dump all services whose component contains the first arg as a substring
8006 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008007 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8008 int opti, boolean dumpAll) {
8009 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008010
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008011 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008012 synchronized (this) {
8013 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008014 services.add(r1);
8015 }
8016 }
8017 } else {
8018 ComponentName componentName = name != null
8019 ? ComponentName.unflattenFromString(name) : null;
8020 int objectId = 0;
8021 if (componentName == null) {
8022 // Not a '/' separated full component name; maybe an object ID?
8023 try {
8024 objectId = Integer.parseInt(name, 16);
8025 name = null;
8026 componentName = null;
8027 } catch (RuntimeException e) {
8028 }
8029 }
8030
8031 synchronized (this) {
8032 for (ServiceRecord r1 : mServices.values()) {
8033 if (componentName != null) {
8034 if (r1.name.equals(componentName)) {
8035 services.add(r1);
8036 }
8037 } else if (name != null) {
8038 if (r1.name.flattenToString().contains(name)) {
8039 services.add(r1);
8040 }
8041 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008042 services.add(r1);
8043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008044 }
8045 }
8046 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008047
8048 if (services.size() <= 0) {
8049 return false;
8050 }
8051
8052 boolean needSep = false;
8053 for (int i=0; i<services.size(); i++) {
8054 if (needSep) {
8055 pw.println();
8056 }
8057 needSep = true;
8058 dumpService("", fd, pw, services.get(i), args, dumpAll);
8059 }
8060 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008061 }
8062
8063 /**
8064 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8065 * there is a thread associated with the service.
8066 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008067 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8068 final ServiceRecord r, String[] args, boolean dumpAll) {
8069 String innerPrefix = prefix + " ";
8070 synchronized (this) {
8071 pw.print(prefix); pw.print("SERVICE ");
8072 pw.print(r.shortName); pw.print(" ");
8073 pw.print(Integer.toHexString(System.identityHashCode(r)));
8074 pw.print(" pid=");
8075 if (r.app != null) pw.println(r.app.pid);
8076 else pw.println("(not running)");
8077 if (dumpAll) {
8078 r.dump(pw, innerPrefix);
8079 }
8080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008081 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008082 pw.print(prefix); pw.println(" Client:");
8083 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008084 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008085 TransferPipe tp = new TransferPipe();
8086 try {
8087 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8088 tp.setBufferPrefix(prefix + " ");
8089 tp.go(fd);
8090 } finally {
8091 tp.kill();
8092 }
8093 } catch (IOException e) {
8094 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008095 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008096 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008097 }
8098 }
8099 }
8100
Dianne Hackborn625ac272010-09-17 18:29:22 -07008101 /**
8102 * There are three things that cmd can be:
8103 * - a flattened component name that matched an existing activity
8104 * - the cmd arg isn't the flattened component name of an existing activity:
8105 * dump all activity whose component contains the cmd as a substring
8106 * - A hex number of the ActivityRecord object instance.
8107 */
8108 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8109 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008110 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008111
8112 if ("all".equals(name)) {
8113 synchronized (this) {
8114 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008115 activities.add(r1);
8116 }
8117 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008118 } else if ("top".equals(name)) {
8119 synchronized (this) {
8120 final int N = mMainStack.mHistory.size();
8121 if (N > 0) {
8122 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8123 }
8124 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008125 } else {
8126 ComponentName componentName = ComponentName.unflattenFromString(name);
8127 int objectId = 0;
8128 if (componentName == null) {
8129 // Not a '/' separated full component name; maybe an object ID?
8130 try {
8131 objectId = Integer.parseInt(name, 16);
8132 name = null;
8133 componentName = null;
8134 } catch (RuntimeException e) {
8135 }
8136 }
8137
8138 synchronized (this) {
8139 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8140 if (componentName != null) {
8141 if (r1.intent.getComponent().equals(componentName)) {
8142 activities.add(r1);
8143 }
8144 } else if (name != null) {
8145 if (r1.intent.getComponent().flattenToString().contains(name)) {
8146 activities.add(r1);
8147 }
8148 } else if (System.identityHashCode(r1) == objectId) {
8149 activities.add(r1);
8150 }
8151 }
8152 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008153 }
8154
8155 if (activities.size() <= 0) {
8156 return false;
8157 }
8158
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008159 String[] newArgs = new String[args.length - opti];
8160 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8161
Dianne Hackborn30d71892010-12-11 10:37:55 -08008162 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008163 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008164 for (int i=activities.size()-1; i>=0; i--) {
8165 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008166 if (needSep) {
8167 pw.println();
8168 }
8169 needSep = true;
8170 synchronized (this) {
8171 if (lastTask != r.task) {
8172 lastTask = r.task;
8173 pw.print("TASK "); pw.print(lastTask.affinity);
8174 pw.print(" id="); pw.println(lastTask.taskId);
8175 if (dumpAll) {
8176 lastTask.dump(pw, " ");
8177 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008178 }
8179 }
8180 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008181 }
8182 return true;
8183 }
8184
8185 /**
8186 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8187 * there is a thread associated with the activity.
8188 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008189 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008190 final ActivityRecord r, String[] args, boolean dumpAll) {
8191 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008192 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008193 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8194 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8195 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008196 if (r.app != null) pw.println(r.app.pid);
8197 else pw.println("(not running)");
8198 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008199 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008200 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008201 }
8202 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008203 // flush anything that is already in the PrintWriter since the thread is going
8204 // to write to the file descriptor directly
8205 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008206 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008207 TransferPipe tp = new TransferPipe();
8208 try {
8209 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8210 innerPrefix, args);
8211 tp.go(fd);
8212 } finally {
8213 tp.kill();
8214 }
8215 } catch (IOException e) {
8216 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008217 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008218 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008219 }
8220 }
8221 }
8222
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008223 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8224 int opti, boolean dumpAll) {
8225 boolean needSep = false;
8226
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008227 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008228 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008229 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008230 pw.println(" Registered Receivers:");
8231 Iterator it = mRegisteredReceivers.values().iterator();
8232 while (it.hasNext()) {
8233 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008234 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008235 r.dump(pw, " ");
8236 }
8237 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008238
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008239 pw.println();
8240 pw.println(" Receiver Resolver Table:");
8241 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008242 needSep = true;
8243 }
8244
8245 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8246 || mPendingBroadcast != null) {
8247 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008248 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008249 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008250 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008251 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8252 pw.println(" Broadcast #" + i + ":");
8253 mParallelBroadcasts.get(i).dump(pw, " ");
8254 }
8255 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008256 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008257 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008258 }
8259 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8260 pw.println(" Serialized Broadcast #" + i + ":");
8261 mOrderedBroadcasts.get(i).dump(pw, " ");
8262 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008263 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008264 pw.println(" Pending broadcast:");
8265 if (mPendingBroadcast != null) {
8266 mPendingBroadcast.dump(pw, " ");
8267 } else {
8268 pw.println(" (null)");
8269 }
8270 needSep = true;
8271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008272
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008273 if (needSep) {
8274 pw.println();
8275 }
8276 pw.println(" Historical broadcasts:");
8277 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8278 BroadcastRecord r = mBroadcastHistory[i];
8279 if (r == null) {
8280 break;
8281 }
8282 if (dumpAll) {
8283 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8284 r.dump(pw, " ");
8285 } else {
8286 if (i >= 50) {
8287 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008288 break;
8289 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008290 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008291 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008292 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008293 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008294
8295 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008296 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008297 pw.println(" Sticky broadcasts:");
8298 StringBuilder sb = new StringBuilder(128);
8299 for (Map.Entry<String, ArrayList<Intent>> ent
8300 : mStickyBroadcasts.entrySet()) {
8301 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008302 if (dumpAll) {
8303 pw.println(":");
8304 ArrayList<Intent> intents = ent.getValue();
8305 final int N = intents.size();
8306 for (int i=0; i<N; i++) {
8307 sb.setLength(0);
8308 sb.append(" Intent: ");
8309 intents.get(i).toShortString(sb, true, false);
8310 pw.println(sb.toString());
8311 Bundle bundle = intents.get(i).getExtras();
8312 if (bundle != null) {
8313 pw.print(" ");
8314 pw.println(bundle.toString());
8315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008316 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008317 } else {
8318 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008319 }
8320 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008321 needSep = true;
8322 }
8323
8324 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008325 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008326 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008327 pw.println(" mHandler:");
8328 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008329 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008330 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008331
8332 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008333 }
8334
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008335 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008336 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008337 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008338
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008339 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8340 if (mServices.size() > 0) {
8341 pw.println(" Active services:");
8342 long nowReal = SystemClock.elapsedRealtime();
8343 Iterator<ServiceRecord> it = mServices.values().iterator();
8344 needSep = false;
8345 while (it.hasNext()) {
8346 ServiceRecord r = it.next();
8347 if (needSep) {
8348 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008349 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008350 pw.print(" * "); pw.println(r);
8351 if (dumpAll) {
8352 r.dump(pw, " ");
8353 needSep = true;
8354 } else {
8355 pw.print(" app="); pw.println(r.app);
8356 pw.print(" created=");
8357 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8358 pw.print(" started="); pw.print(r.startRequested);
8359 pw.print(" connections="); pw.println(r.connections.size());
8360 }
8361 if (dumpClient && r.app != null && r.app.thread != null) {
8362 pw.println(" Client:");
8363 pw.flush();
8364 try {
8365 TransferPipe tp = new TransferPipe();
8366 try {
8367 r.app.thread.dumpService(
8368 tp.getWriteFd().getFileDescriptor(), r, args);
8369 tp.setBufferPrefix(" ");
8370 // Short timeout, since blocking here can
8371 // deadlock with the application.
8372 tp.go(fd, 2000);
8373 } finally {
8374 tp.kill();
8375 }
8376 } catch (IOException e) {
8377 pw.println(" Failure while dumping the service: " + e);
8378 } catch (RemoteException e) {
8379 pw.println(" Got a RemoteException while dumping the service");
8380 }
8381 needSep = true;
8382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008383 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008384 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008386
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008387 if (mPendingServices.size() > 0) {
8388 if (needSep) pw.println(" ");
8389 pw.println(" Pending services:");
8390 for (int i=0; i<mPendingServices.size(); i++) {
8391 ServiceRecord r = mPendingServices.get(i);
8392 pw.print(" * Pending "); pw.println(r);
8393 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008394 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008395 needSep = true;
8396 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008397
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008398 if (mRestartingServices.size() > 0) {
8399 if (needSep) pw.println(" ");
8400 pw.println(" Restarting services:");
8401 for (int i=0; i<mRestartingServices.size(); i++) {
8402 ServiceRecord r = mRestartingServices.get(i);
8403 pw.print(" * Restarting "); pw.println(r);
8404 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008405 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008406 needSep = true;
8407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008408
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008409 if (mStoppingServices.size() > 0) {
8410 if (needSep) pw.println(" ");
8411 pw.println(" Stopping services:");
8412 for (int i=0; i<mStoppingServices.size(); i++) {
8413 ServiceRecord r = mStoppingServices.get(i);
8414 pw.print(" * Stopping "); pw.println(r);
8415 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008416 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008417 needSep = true;
8418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008419
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008420 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008421 if (mServiceConnections.size() > 0) {
8422 if (needSep) pw.println(" ");
8423 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008424 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008425 = mServiceConnections.values().iterator();
8426 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008427 ArrayList<ConnectionRecord> r = it.next();
8428 for (int i=0; i<r.size(); i++) {
8429 pw.print(" * "); pw.println(r.get(i));
8430 r.get(i).dump(pw, " ");
8431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008432 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008433 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008434 }
8435 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008436
8437 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438 }
8439
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008440 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8441 int opti, boolean dumpAll) {
8442 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008443
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008444 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8445 if (mProvidersByClass.size() > 0) {
8446 if (needSep) pw.println(" ");
8447 pw.println(" Published content providers (by class):");
8448 Iterator<Map.Entry<String, ContentProviderRecord>> it
8449 = mProvidersByClass.entrySet().iterator();
8450 while (it.hasNext()) {
8451 Map.Entry<String, ContentProviderRecord> e = it.next();
8452 ContentProviderRecord r = e.getValue();
8453 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008454 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008455 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008456 } else {
8457 pw.print(" * "); pw.print(r.name.toShortString());
8458 if (r.app != null) {
8459 pw.println(":");
8460 pw.print(" "); pw.println(r.app);
8461 } else {
8462 pw.println();
8463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008466 needSep = true;
8467 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008468
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008469 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008470 if (mProvidersByName.size() > 0) {
8471 pw.println(" ");
8472 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008473 Iterator<Map.Entry<String, ContentProviderRecord>> it
8474 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008475 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008476 Map.Entry<String, ContentProviderRecord> e = it.next();
8477 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008478 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8479 pw.println(r);
8480 }
8481 needSep = true;
8482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008483 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008484
8485 if (mLaunchingProviders.size() > 0) {
8486 if (needSep) pw.println(" ");
8487 pw.println(" Launching content providers:");
8488 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8489 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8490 pw.println(mLaunchingProviders.get(i));
8491 }
8492 needSep = true;
8493 }
8494
8495 if (mGrantedUriPermissions.size() > 0) {
8496 pw.println();
8497 pw.println("Granted Uri Permissions:");
8498 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8499 int uid = mGrantedUriPermissions.keyAt(i);
8500 HashMap<Uri, UriPermission> perms
8501 = mGrantedUriPermissions.valueAt(i);
8502 pw.print(" * UID "); pw.print(uid);
8503 pw.println(" holds:");
8504 for (UriPermission perm : perms.values()) {
8505 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008506 if (dumpAll) {
8507 perm.dump(pw, " ");
8508 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008509 }
8510 }
8511 needSep = true;
8512 }
8513
8514 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008515 }
8516
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008517 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8518 int opti, boolean dumpAll) {
8519 boolean needSep = false;
8520
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008521 if (this.mIntentSenderRecords.size() > 0) {
8522 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8523 Iterator<WeakReference<PendingIntentRecord>> it
8524 = mIntentSenderRecords.values().iterator();
8525 while (it.hasNext()) {
8526 WeakReference<PendingIntentRecord> ref = it.next();
8527 PendingIntentRecord rec = ref != null ? ref.get(): null;
8528 needSep = true;
8529 if (rec != null) {
8530 pw.print(" * "); pw.println(rec);
8531 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008533 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008534 } else {
8535 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008536 }
8537 }
8538 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008539
8540 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008541 }
8542
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008543 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8544 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008545 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008546 boolean needNL = false;
8547 final String innerPrefix = prefix + " ";
8548 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008549 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008550 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008551 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008552 if (needNL) {
8553 pw.println(" ");
8554 needNL = false;
8555 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008556 if (lastTask != r.task) {
8557 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008558 pw.print(prefix);
8559 pw.print(full ? "* " : " ");
8560 pw.println(lastTask);
8561 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008562 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008563 } else if (complete) {
8564 // Complete + brief == give a summary. Isn't that obvious?!?
8565 if (lastTask.intent != null) {
8566 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8567 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008569 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008570 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8571 pw.print(" #"); pw.print(i); pw.print(": ");
8572 pw.println(r);
8573 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008574 r.dump(pw, innerPrefix);
8575 } else if (complete) {
8576 // Complete + brief == give a summary. Isn't that obvious?!?
8577 pw.print(innerPrefix); pw.println(r.intent);
8578 if (r.app != null) {
8579 pw.print(innerPrefix); pw.println(r.app);
8580 }
8581 }
8582 if (client && r.app != null && r.app.thread != null) {
8583 // flush anything that is already in the PrintWriter since the thread is going
8584 // to write to the file descriptor directly
8585 pw.flush();
8586 try {
8587 TransferPipe tp = new TransferPipe();
8588 try {
8589 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8590 innerPrefix, args);
8591 // Short timeout, since blocking here can
8592 // deadlock with the application.
8593 tp.go(fd, 2000);
8594 } finally {
8595 tp.kill();
8596 }
8597 } catch (IOException e) {
8598 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8599 } catch (RemoteException e) {
8600 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8601 }
8602 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008604 }
8605 }
8606
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008607 private static String buildOomTag(String prefix, String space, int val, int base) {
8608 if (val == base) {
8609 if (space == null) return prefix;
8610 return prefix + " ";
8611 }
8612 return prefix + "+" + Integer.toString(val-base);
8613 }
8614
8615 private static final int dumpProcessList(PrintWriter pw,
8616 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008617 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008619 final int N = list.size()-1;
8620 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008621 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008622 pw.println(String.format("%s%s #%2d: %s",
8623 prefix, (r.persistent ? persistentLabel : normalLabel),
8624 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008625 if (r.persistent) {
8626 numPers++;
8627 }
8628 }
8629 return numPers;
8630 }
8631
Dianne Hackborn287952c2010-09-22 22:34:31 -07008632 private static final void dumpProcessOomList(PrintWriter pw,
8633 ActivityManagerService service, List<ProcessRecord> list,
8634 String prefix, String normalLabel, String persistentLabel,
8635 boolean inclDetails) {
8636
8637 final long curRealtime = SystemClock.elapsedRealtime();
8638 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8639 final long curUptime = SystemClock.uptimeMillis();
8640 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8641
8642 final int N = list.size()-1;
8643 for (int i=N; i>=0; i--) {
8644 ProcessRecord r = list.get(i);
8645 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008646 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8647 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8648 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8649 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8650 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8651 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8652 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8653 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8654 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8655 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8656 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8657 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8658 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8659 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8660 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8661 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8662 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8663 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8664 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8665 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8666 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8667 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008668 } else {
8669 oomAdj = Integer.toString(r.setAdj);
8670 }
8671 String schedGroup;
8672 switch (r.setSchedGroup) {
8673 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8674 schedGroup = "B";
8675 break;
8676 case Process.THREAD_GROUP_DEFAULT:
8677 schedGroup = "F";
8678 break;
8679 default:
8680 schedGroup = Integer.toString(r.setSchedGroup);
8681 break;
8682 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008683 String foreground;
8684 if (r.foregroundActivities) {
8685 foreground = "A";
8686 } else if (r.foregroundServices) {
8687 foreground = "S";
8688 } else {
8689 foreground = " ";
8690 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008691 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008692 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008693 N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
8694 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008695 if (r.adjSource != null || r.adjTarget != null) {
8696 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008697 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008698 if (r.adjTarget instanceof ComponentName) {
8699 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8700 } else if (r.adjTarget != null) {
8701 pw.print(r.adjTarget.toString());
8702 } else {
8703 pw.print("{null}");
8704 }
8705 pw.print("<=");
8706 if (r.adjSource instanceof ProcessRecord) {
8707 pw.print("Proc{");
8708 pw.print(((ProcessRecord)r.adjSource).toShortString());
8709 pw.println("}");
8710 } else if (r.adjSource != null) {
8711 pw.println(r.adjSource.toString());
8712 } else {
8713 pw.println("{null}");
8714 }
8715 }
8716 if (inclDetails) {
8717 pw.print(prefix);
8718 pw.print(" ");
8719 pw.print("oom: max="); pw.print(r.maxAdj);
8720 pw.print(" hidden="); pw.print(r.hiddenAdj);
8721 pw.print(" curRaw="); pw.print(r.curRawAdj);
8722 pw.print(" setRaw="); pw.print(r.setRawAdj);
8723 pw.print(" cur="); pw.print(r.curAdj);
8724 pw.print(" set="); pw.println(r.setAdj);
8725 pw.print(prefix);
8726 pw.print(" ");
8727 pw.print("keeping="); pw.print(r.keeping);
8728 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008729 pw.print(" empty="); pw.print(r.empty);
8730 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008731
8732 if (!r.keeping) {
8733 if (r.lastWakeTime != 0) {
8734 long wtime;
8735 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8736 synchronized (stats) {
8737 wtime = stats.getProcessWakeTime(r.info.uid,
8738 r.pid, curRealtime);
8739 }
8740 long timeUsed = wtime - r.lastWakeTime;
8741 pw.print(prefix);
8742 pw.print(" ");
8743 pw.print("keep awake over ");
8744 TimeUtils.formatDuration(realtimeSince, pw);
8745 pw.print(" used ");
8746 TimeUtils.formatDuration(timeUsed, pw);
8747 pw.print(" (");
8748 pw.print((timeUsed*100)/realtimeSince);
8749 pw.println("%)");
8750 }
8751 if (r.lastCpuTime != 0) {
8752 long timeUsed = r.curCpuTime - r.lastCpuTime;
8753 pw.print(prefix);
8754 pw.print(" ");
8755 pw.print("run cpu over ");
8756 TimeUtils.formatDuration(uptimeSince, pw);
8757 pw.print(" used ");
8758 TimeUtils.formatDuration(timeUsed, pw);
8759 pw.print(" (");
8760 pw.print((timeUsed*100)/uptimeSince);
8761 pw.println("%)");
8762 }
8763 }
8764 }
8765 }
8766 }
8767
Dianne Hackbornb437e092011-08-05 17:50:29 -07008768 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008769 ArrayList<ProcessRecord> procs;
8770 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008771 if (args != null && args.length > start
8772 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008773 procs = new ArrayList<ProcessRecord>();
8774 int pid = -1;
8775 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008776 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008777 } catch (NumberFormatException e) {
8778
8779 }
8780 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8781 ProcessRecord proc = mLruProcesses.get(i);
8782 if (proc.pid == pid) {
8783 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07008784 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008785 procs.add(proc);
8786 }
8787 }
8788 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008789 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008790 return null;
8791 }
8792 } else {
8793 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8794 }
8795 }
8796 return procs;
8797 }
8798
8799 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8800 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008801 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008802 if (procs == null) {
8803 return;
8804 }
8805
8806 long uptime = SystemClock.uptimeMillis();
8807 long realtime = SystemClock.elapsedRealtime();
8808 pw.println("Applications Graphics Acceleration Info:");
8809 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8810
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008811 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8812 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008813 if (r.thread != null) {
8814 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8815 pw.flush();
8816 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008817 TransferPipe tp = new TransferPipe();
8818 try {
8819 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
8820 tp.go(fd);
8821 } finally {
8822 tp.kill();
8823 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008824 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008825 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008826 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008827 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008828 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008829 pw.flush();
8830 }
8831 }
8832 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008833 }
8834
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008835 final static class MemItem {
8836 final String label;
8837 final long pss;
8838
8839 public MemItem(String _label, long _pss) {
8840 label = _label;
8841 pss = _pss;
8842 }
8843 }
8844
Dianne Hackbornb437e092011-08-05 17:50:29 -07008845 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
8846 boolean sort) {
8847 if (sort) {
8848 Collections.sort(items, new Comparator<MemItem>() {
8849 @Override
8850 public int compare(MemItem lhs, MemItem rhs) {
8851 if (lhs.pss < rhs.pss) {
8852 return 1;
8853 } else if (lhs.pss > rhs.pss) {
8854 return -1;
8855 }
8856 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008857 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07008858 });
8859 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008860
8861 for (int i=0; i<items.size(); i++) {
8862 MemItem mi = items.get(i);
8863 pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
8864 }
8865 }
8866
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008867 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8868 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008869 boolean dumpAll = false;
8870
8871 int opti = 0;
8872 while (opti < args.length) {
8873 String opt = args[opti];
8874 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8875 break;
8876 }
8877 opti++;
8878 if ("-a".equals(opt)) {
8879 dumpAll = true;
8880 } else if ("-h".equals(opt)) {
8881 pw.println("meminfo dump options: [-a] [process]");
8882 pw.println(" -a: include all available information for each process.");
8883 pw.println("If [process] is specified it can be the name or ");
8884 pw.println("pid of a specific process to dump.");
8885 return;
8886 } else {
8887 pw.println("Unknown argument: " + opt + "; use -h for help");
8888 }
8889 }
8890
8891 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008892 if (procs == null) {
8893 return;
8894 }
8895
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008896 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008897 long uptime = SystemClock.uptimeMillis();
8898 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07008899
8900 if (procs.size() == 1 || isCheckinRequest) {
8901 dumpAll = true;
8902 }
8903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008904 if (isCheckinRequest) {
8905 // short checkin version
8906 pw.println(uptime + "," + realtime);
8907 pw.flush();
8908 } else {
8909 pw.println("Applications Memory Usage (kB):");
8910 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8911 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008912
Dianne Hackbornb437e092011-08-05 17:50:29 -07008913 String[] innerArgs = new String[args.length-opti];
8914 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
8915
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008916 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
8917 long nativePss=0, dalvikPss=0, otherPss=0;
8918 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
8919
Dianne Hackbornb437e092011-08-05 17:50:29 -07008920 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07008921 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
8922 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
8923 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07008924 };
8925 final String[] oomLabel = new String[] {
8926 "System", "Persistent", "Foreground",
8927 "Visible", "Perceptible", "Heavy Weight",
8928 "Backup", "Services", "Home", "Background"
8929 };
8930 long oomPss[] = new long[oomLabel.length];
8931
8932 long totalPss = 0;
8933
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008934 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8935 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008936 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008937 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008938 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
8939 pw.flush();
8940 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008941 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07008942 if (dumpAll) {
8943 try {
8944 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
8945 } catch (RemoteException e) {
8946 if (!isCheckinRequest) {
8947 pw.println("Got RemoteException!");
8948 pw.flush();
8949 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008950 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07008951 } else {
8952 mi = new Debug.MemoryInfo();
8953 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008954 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07008955
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008956 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008957 long myTotalPss = mi.getTotalPss();
8958 totalPss += myTotalPss;
8959 procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008960
8961 nativePss += mi.nativePss;
8962 dalvikPss += mi.dalvikPss;
8963 otherPss += mi.otherPss;
8964 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
8965 long mem = mi.getOtherPss(j);
8966 miscPss[j] += mem;
8967 otherPss -= mem;
8968 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07008969
8970 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
8971 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
8972 oomPss[oomIndex] += myTotalPss;
8973 break;
8974 }
8975 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008976 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 }
8978 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008979
8980 if (!isCheckinRequest && procs.size() > 1) {
8981 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
8982
8983 catMems.add(new MemItem("Native", nativePss));
8984 catMems.add(new MemItem("Dalvik", dalvikPss));
8985 catMems.add(new MemItem("Unknown", otherPss));
8986 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
8987 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
8988 }
8989
Dianne Hackbornb437e092011-08-05 17:50:29 -07008990 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
8991 for (int j=0; j<oomPss.length; j++) {
8992 if (oomPss[j] != 0) {
8993 oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
8994 }
8995 }
8996
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008997 pw.println();
8998 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07008999 dumpMemItems(pw, " ", procMems, true);
9000 pw.println();
9001 pw.println("Total PSS by OOM adjustment:");
9002 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009003 pw.println();
9004 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009005 dumpMemItems(pw, " ", catMems, true);
9006 pw.println();
9007 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009 }
9010
9011 /**
9012 * Searches array of arguments for the specified string
9013 * @param args array of argument strings
9014 * @param value value to search for
9015 * @return true if the value is contained in the array
9016 */
9017 private static boolean scanArgs(String[] args, String value) {
9018 if (args != null) {
9019 for (String arg : args) {
9020 if (value.equals(arg)) {
9021 return true;
9022 }
9023 }
9024 }
9025 return false;
9026 }
9027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009028 private final void killServicesLocked(ProcessRecord app,
9029 boolean allowRestart) {
9030 // Report disconnected services.
9031 if (false) {
9032 // XXX we are letting the client link to the service for
9033 // death notifications.
9034 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009035 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009036 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009037 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009038 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009039 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009040 = r.connections.values().iterator();
9041 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009042 ArrayList<ConnectionRecord> cl = jt.next();
9043 for (int i=0; i<cl.size(); i++) {
9044 ConnectionRecord c = cl.get(i);
9045 if (c.binding.client != app) {
9046 try {
9047 //c.conn.connected(r.className, null);
9048 } catch (Exception e) {
9049 // todo: this should be asynchronous!
9050 Slog.w(TAG, "Exception thrown disconnected servce "
9051 + r.shortName
9052 + " from app " + app.processName, e);
9053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009054 }
9055 }
9056 }
9057 }
9058 }
9059 }
9060 }
9061
9062 // Clean up any connections this application has to other services.
9063 if (app.connections.size() > 0) {
9064 Iterator<ConnectionRecord> it = app.connections.iterator();
9065 while (it.hasNext()) {
9066 ConnectionRecord r = it.next();
9067 removeConnectionLocked(r, app, null);
9068 }
9069 }
9070 app.connections.clear();
9071
9072 if (app.services.size() != 0) {
9073 // Any services running in the application need to be placed
9074 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009075 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009076 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009077 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009078 synchronized (sr.stats.getBatteryStats()) {
9079 sr.stats.stopLaunchedLocked();
9080 }
9081 sr.app = null;
9082 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009083 if (mStoppingServices.remove(sr)) {
9084 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9085 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009086
9087 boolean hasClients = sr.bindings.size() > 0;
9088 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009089 Iterator<IntentBindRecord> bindings
9090 = sr.bindings.values().iterator();
9091 while (bindings.hasNext()) {
9092 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009093 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009094 + ": shouldUnbind=" + b.hasBound);
9095 b.binder = null;
9096 b.requested = b.received = b.hasBound = false;
9097 }
9098 }
9099
Dianne Hackborn070783f2010-12-29 16:46:28 -08009100 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9101 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009102 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009103 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009104 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009105 sr.crashCount, sr.shortName, app.pid);
9106 bringDownServiceLocked(sr, true);
9107 } else if (!allowRestart) {
9108 bringDownServiceLocked(sr, true);
9109 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009110 boolean canceled = scheduleServiceRestartLocked(sr, true);
9111
9112 // Should the service remain running? Note that in the
9113 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009114 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009115 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9116 if (sr.pendingStarts.size() == 0) {
9117 sr.startRequested = false;
9118 if (!hasClients) {
9119 // Whoops, no reason to restart!
9120 bringDownServiceLocked(sr, true);
9121 }
9122 }
9123 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009124 }
9125 }
9126
9127 if (!allowRestart) {
9128 app.services.clear();
9129 }
9130 }
9131
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009132 // Make sure we have no more records on the stopping list.
9133 int i = mStoppingServices.size();
9134 while (i > 0) {
9135 i--;
9136 ServiceRecord sr = mStoppingServices.get(i);
9137 if (sr.app == app) {
9138 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009139 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009140 }
9141 }
9142
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009143 app.executingServices.clear();
9144 }
9145
9146 private final void removeDyingProviderLocked(ProcessRecord proc,
9147 ContentProviderRecord cpr) {
9148 synchronized (cpr) {
9149 cpr.launchingApp = null;
9150 cpr.notifyAll();
9151 }
9152
9153 mProvidersByClass.remove(cpr.info.name);
9154 String names[] = cpr.info.authority.split(";");
9155 for (int j = 0; j < names.length; j++) {
9156 mProvidersByName.remove(names[j]);
9157 }
9158
9159 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9160 while (cit.hasNext()) {
9161 ProcessRecord capp = cit.next();
9162 if (!capp.persistent && capp.thread != null
9163 && capp.pid != 0
9164 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009165 Slog.i(TAG, "Kill " + capp.processName
9166 + " (pid " + capp.pid + "): provider " + cpr.info.name
9167 + " in dying process " + proc.processName);
9168 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9169 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009170 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009171 }
9172 }
9173
9174 mLaunchingProviders.remove(cpr);
9175 }
9176
9177 /**
9178 * Main code for cleaning up a process when it has gone away. This is
9179 * called both as a result of the process dying, or directly when stopping
9180 * a process when running in single process mode.
9181 */
9182 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009183 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009184 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009185 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009186 }
9187
Dianne Hackborn36124872009-10-08 16:22:03 -07009188 mProcessesToGc.remove(app);
9189
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009190 // Dismiss any open dialogs.
9191 if (app.crashDialog != null) {
9192 app.crashDialog.dismiss();
9193 app.crashDialog = null;
9194 }
9195 if (app.anrDialog != null) {
9196 app.anrDialog.dismiss();
9197 app.anrDialog = null;
9198 }
9199 if (app.waitDialog != null) {
9200 app.waitDialog.dismiss();
9201 app.waitDialog = null;
9202 }
9203
9204 app.crashing = false;
9205 app.notResponding = false;
9206
9207 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009208 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009209 app.thread = null;
9210 app.forcingToForeground = null;
9211 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009212 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009213 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009214 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009215
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009216 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009217
9218 boolean restart = false;
9219
9220 int NL = mLaunchingProviders.size();
9221
9222 // Remove published content providers.
9223 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009224 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009225 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009226 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009227 cpr.provider = null;
9228 cpr.app = null;
9229
9230 // See if someone is waiting for this provider... in which
9231 // case we don't remove it, but just let it restart.
9232 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009233 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009234 for (; i<NL; i++) {
9235 if (mLaunchingProviders.get(i) == cpr) {
9236 restart = true;
9237 break;
9238 }
9239 }
9240 } else {
9241 i = NL;
9242 }
9243
9244 if (i >= NL) {
9245 removeDyingProviderLocked(app, cpr);
9246 NL = mLaunchingProviders.size();
9247 }
9248 }
9249 app.pubProviders.clear();
9250 }
9251
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009252 // Take care of any launching providers waiting for this process.
9253 if (checkAppInLaunchingProvidersLocked(app, false)) {
9254 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009255 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009257 // Unregister from connected content providers.
9258 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009259 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009260 while (it.hasNext()) {
9261 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9262 cpr.clients.remove(app);
9263 }
9264 app.conProviders.clear();
9265 }
9266
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009267 // At this point there may be remaining entries in mLaunchingProviders
9268 // where we were the only one waiting, so they are no longer of use.
9269 // Look for these and clean up if found.
9270 // XXX Commented out for now. Trying to figure out a way to reproduce
9271 // the actual situation to identify what is actually going on.
9272 if (false) {
9273 for (int i=0; i<NL; i++) {
9274 ContentProviderRecord cpr = (ContentProviderRecord)
9275 mLaunchingProviders.get(i);
9276 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9277 synchronized (cpr) {
9278 cpr.launchingApp = null;
9279 cpr.notifyAll();
9280 }
9281 }
9282 }
9283 }
9284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009285 skipCurrentReceiverLocked(app);
9286
9287 // Unregister any receivers.
9288 if (app.receivers.size() > 0) {
9289 Iterator<ReceiverList> it = app.receivers.iterator();
9290 while (it.hasNext()) {
9291 removeReceiverLocked(it.next());
9292 }
9293 app.receivers.clear();
9294 }
9295
Christopher Tate181fafa2009-05-14 11:12:14 -07009296 // If the app is undergoing backup, tell the backup manager about it
9297 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009298 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009299 try {
9300 IBackupManager bm = IBackupManager.Stub.asInterface(
9301 ServiceManager.getService(Context.BACKUP_SERVICE));
9302 bm.agentDisconnected(app.info.packageName);
9303 } catch (RemoteException e) {
9304 // can't happen; backup manager is local
9305 }
9306 }
9307
Jeff Sharkey287bd832011-05-28 19:36:26 -07009308 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009310 // If the caller is restarting this app, then leave it in its
9311 // current lists and let the caller take care of it.
9312 if (restarting) {
9313 return;
9314 }
9315
9316 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009317 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 "Removing non-persistent process during cleanup: " + app);
9319 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009320 if (mHeavyWeightProcess == app) {
9321 mHeavyWeightProcess = null;
9322 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009324 } else if (!app.removed) {
9325 // This app is persistent, so we need to keep its record around.
9326 // If it is not already on the pending app list, add it there
9327 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009328 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9329 mPersistentStartingProcesses.add(app);
9330 restart = true;
9331 }
9332 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009333 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9334 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009335 mProcessesOnHold.remove(app);
9336
The Android Open Source Project4df24232009-03-05 14:34:35 -08009337 if (app == mHomeProcess) {
9338 mHomeProcess = null;
9339 }
9340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009341 if (restart) {
9342 // We have components that still need to be running in the
9343 // process, so re-launch it.
9344 mProcessNames.put(app.processName, app.info.uid, app);
9345 startProcessLocked(app, "restart", app.processName);
9346 } else if (app.pid > 0 && app.pid != MY_PID) {
9347 // Goodbye!
9348 synchronized (mPidsSelfLocked) {
9349 mPidsSelfLocked.remove(app.pid);
9350 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9351 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009352 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009353 }
9354 }
9355
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009356 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9357 // Look through the content providers we are waiting to have launched,
9358 // and if any run in this process then either schedule a restart of
9359 // the process or kill the client waiting for it if this process has
9360 // gone bad.
9361 int NL = mLaunchingProviders.size();
9362 boolean restart = false;
9363 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009364 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009365 if (cpr.launchingApp == app) {
9366 if (!alwaysBad && !app.bad) {
9367 restart = true;
9368 } else {
9369 removeDyingProviderLocked(app, cpr);
9370 NL = mLaunchingProviders.size();
9371 }
9372 }
9373 }
9374 return restart;
9375 }
9376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009377 // =========================================================
9378 // SERVICES
9379 // =========================================================
9380
9381 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9382 ActivityManager.RunningServiceInfo info =
9383 new ActivityManager.RunningServiceInfo();
9384 info.service = r.name;
9385 if (r.app != null) {
9386 info.pid = r.app.pid;
9387 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009388 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009389 info.process = r.processName;
9390 info.foreground = r.isForeground;
9391 info.activeSince = r.createTime;
9392 info.started = r.startRequested;
9393 info.clientCount = r.connections.size();
9394 info.crashCount = r.crashCount;
9395 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009396 if (r.isForeground) {
9397 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9398 }
9399 if (r.startRequested) {
9400 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9401 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009402 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009403 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9404 }
9405 if (r.app != null && r.app.persistent) {
9406 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9407 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009408
9409 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9410 for (int i=0; i<connl.size(); i++) {
9411 ConnectionRecord conn = connl.get(i);
9412 if (conn.clientLabel != 0) {
9413 info.clientPackage = conn.binding.client.info.packageName;
9414 info.clientLabel = conn.clientLabel;
9415 return info;
9416 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009417 }
9418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009419 return info;
9420 }
9421
9422 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9423 int flags) {
9424 synchronized (this) {
9425 ArrayList<ActivityManager.RunningServiceInfo> res
9426 = new ArrayList<ActivityManager.RunningServiceInfo>();
9427
9428 if (mServices.size() > 0) {
9429 Iterator<ServiceRecord> it = mServices.values().iterator();
9430 while (it.hasNext() && res.size() < maxNum) {
9431 res.add(makeRunningServiceInfoLocked(it.next()));
9432 }
9433 }
9434
9435 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9436 ServiceRecord r = mRestartingServices.get(i);
9437 ActivityManager.RunningServiceInfo info =
9438 makeRunningServiceInfoLocked(r);
9439 info.restarting = r.nextRestartTime;
9440 res.add(info);
9441 }
9442
9443 return res;
9444 }
9445 }
9446
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009447 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9448 synchronized (this) {
9449 ServiceRecord r = mServices.get(name);
9450 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009451 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9452 for (int i=0; i<conn.size(); i++) {
9453 if (conn.get(i).clientIntent != null) {
9454 return conn.get(i).clientIntent;
9455 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009456 }
9457 }
9458 }
9459 }
9460 return null;
9461 }
9462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009463 private final ServiceRecord findServiceLocked(ComponentName name,
9464 IBinder token) {
9465 ServiceRecord r = mServices.get(name);
9466 return r == token ? r : null;
9467 }
9468
9469 private final class ServiceLookupResult {
9470 final ServiceRecord record;
9471 final String permission;
9472
9473 ServiceLookupResult(ServiceRecord _record, String _permission) {
9474 record = _record;
9475 permission = _permission;
9476 }
9477 };
9478
9479 private ServiceLookupResult findServiceLocked(Intent service,
9480 String resolvedType) {
9481 ServiceRecord r = null;
9482 if (service.getComponent() != null) {
9483 r = mServices.get(service.getComponent());
9484 }
9485 if (r == null) {
9486 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9487 r = mServicesByIntent.get(filter);
9488 }
9489
9490 if (r == null) {
9491 try {
9492 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009493 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009494 service, resolvedType, 0);
9495 ServiceInfo sInfo =
9496 rInfo != null ? rInfo.serviceInfo : null;
9497 if (sInfo == null) {
9498 return null;
9499 }
9500
9501 ComponentName name = new ComponentName(
9502 sInfo.applicationInfo.packageName, sInfo.name);
9503 r = mServices.get(name);
9504 } catch (RemoteException ex) {
9505 // pm is in same process, this will never happen.
9506 }
9507 }
9508 if (r != null) {
9509 int callingPid = Binder.getCallingPid();
9510 int callingUid = Binder.getCallingUid();
9511 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009512 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009513 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009514 if (!r.exported) {
9515 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9516 + " from pid=" + callingPid
9517 + ", uid=" + callingUid
9518 + " that is not exported from uid " + r.appInfo.uid);
9519 return new ServiceLookupResult(null, "not exported from uid "
9520 + r.appInfo.uid);
9521 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009522 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009523 + " from pid=" + callingPid
9524 + ", uid=" + callingUid
9525 + " requires " + r.permission);
9526 return new ServiceLookupResult(null, r.permission);
9527 }
9528 return new ServiceLookupResult(r, null);
9529 }
9530 return null;
9531 }
9532
9533 private class ServiceRestarter implements Runnable {
9534 private ServiceRecord mService;
9535
9536 void setService(ServiceRecord service) {
9537 mService = service;
9538 }
9539
9540 public void run() {
9541 synchronized(ActivityManagerService.this) {
9542 performServiceRestartLocked(mService);
9543 }
9544 }
9545 }
9546
9547 private ServiceLookupResult retrieveServiceLocked(Intent service,
9548 String resolvedType, int callingPid, int callingUid) {
9549 ServiceRecord r = null;
9550 if (service.getComponent() != null) {
9551 r = mServices.get(service.getComponent());
9552 }
9553 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9554 r = mServicesByIntent.get(filter);
9555 if (r == null) {
9556 try {
9557 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009558 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009559 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009560 ServiceInfo sInfo =
9561 rInfo != null ? rInfo.serviceInfo : null;
9562 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009563 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009564 ": not found");
9565 return null;
9566 }
9567
9568 ComponentName name = new ComponentName(
9569 sInfo.applicationInfo.packageName, sInfo.name);
9570 r = mServices.get(name);
9571 if (r == null) {
9572 filter = new Intent.FilterComparison(service.cloneFilter());
9573 ServiceRestarter res = new ServiceRestarter();
9574 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9575 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9576 synchronized (stats) {
9577 ss = stats.getServiceStatsLocked(
9578 sInfo.applicationInfo.uid, sInfo.packageName,
9579 sInfo.name);
9580 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009581 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009582 res.setService(r);
9583 mServices.put(name, r);
9584 mServicesByIntent.put(filter, r);
9585
9586 // Make sure this component isn't in the pending list.
9587 int N = mPendingServices.size();
9588 for (int i=0; i<N; i++) {
9589 ServiceRecord pr = mPendingServices.get(i);
9590 if (pr.name.equals(name)) {
9591 mPendingServices.remove(i);
9592 i--;
9593 N--;
9594 }
9595 }
9596 }
9597 } catch (RemoteException ex) {
9598 // pm is in same process, this will never happen.
9599 }
9600 }
9601 if (r != null) {
9602 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009603 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009605 if (!r.exported) {
9606 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9607 + " from pid=" + callingPid
9608 + ", uid=" + callingUid
9609 + " that is not exported from uid " + r.appInfo.uid);
9610 return new ServiceLookupResult(null, "not exported from uid "
9611 + r.appInfo.uid);
9612 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009613 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009614 + " from pid=" + callingPid
9615 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009616 + " requires " + r.permission);
9617 return new ServiceLookupResult(null, r.permission);
9618 }
9619 return new ServiceLookupResult(r, null);
9620 }
9621 return null;
9622 }
9623
Dianne Hackborn287952c2010-09-22 22:34:31 -07009624 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9625 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9626 + why + " of " + r + " in app " + r.app);
9627 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9628 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009629 long now = SystemClock.uptimeMillis();
9630 if (r.executeNesting == 0 && r.app != null) {
9631 if (r.app.executingServices.size() == 0) {
9632 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9633 msg.obj = r.app;
9634 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9635 }
9636 r.app.executingServices.add(r);
9637 }
9638 r.executeNesting++;
9639 r.executingStart = now;
9640 }
9641
9642 private final void sendServiceArgsLocked(ServiceRecord r,
9643 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009644 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009645 if (N == 0) {
9646 return;
9647 }
9648
Dianne Hackborn39792d22010-08-19 18:01:52 -07009649 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009650 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009651 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009652 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9653 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009654 if (si.intent == null && N > 1) {
9655 // If somehow we got a dummy null intent in the middle,
9656 // then skip it. DO NOT skip a null intent when it is
9657 // the only one in the list -- this is to support the
9658 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009659 continue;
9660 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009661 si.deliveredTime = SystemClock.uptimeMillis();
9662 r.deliveredStarts.add(si);
9663 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009664 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009665 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009666 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009667 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009668 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009669 if (!oomAdjusted) {
9670 oomAdjusted = true;
9671 updateOomAdjLocked(r.app);
9672 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009673 int flags = 0;
9674 if (si.deliveryCount > 0) {
9675 flags |= Service.START_FLAG_RETRY;
9676 }
9677 if (si.doneExecutingCount > 0) {
9678 flags |= Service.START_FLAG_REDELIVERY;
9679 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009680 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009681 } catch (RemoteException e) {
9682 // Remote process gone... we'll let the normal cleanup take
9683 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009684 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009685 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009686 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009687 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009688 break;
9689 }
9690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009691 }
9692
9693 private final boolean requestServiceBindingLocked(ServiceRecord r,
9694 IntentBindRecord i, boolean rebind) {
9695 if (r.app == null || r.app.thread == null) {
9696 // If service is not currently running, can't yet bind.
9697 return false;
9698 }
9699 if ((!i.requested || rebind) && i.apps.size() > 0) {
9700 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009701 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009702 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9703 if (!rebind) {
9704 i.requested = true;
9705 }
9706 i.hasBound = true;
9707 i.doRebind = false;
9708 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009709 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009710 return false;
9711 }
9712 }
9713 return true;
9714 }
9715
9716 private final void requestServiceBindingsLocked(ServiceRecord r) {
9717 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9718 while (bindings.hasNext()) {
9719 IntentBindRecord i = bindings.next();
9720 if (!requestServiceBindingLocked(r, i, false)) {
9721 break;
9722 }
9723 }
9724 }
9725
9726 private final void realStartServiceLocked(ServiceRecord r,
9727 ProcessRecord app) throws RemoteException {
9728 if (app.thread == null) {
9729 throw new RemoteException();
9730 }
9731
9732 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009733 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009734
9735 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009736 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009737 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009738
9739 boolean created = false;
9740 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009741 mStringBuilder.setLength(0);
9742 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009743 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009744 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009745 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009746 synchronized (r.stats.getBatteryStats()) {
9747 r.stats.startLaunchedLocked();
9748 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009749 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009750 app.thread.scheduleCreateService(r, r.serviceInfo,
9751 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009752 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009753 created = true;
9754 } finally {
9755 if (!created) {
9756 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009757 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009758 }
9759 }
9760
9761 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009762
9763 // If the service is in the started state, and there are no
9764 // pending arguments, then fake up one so its onStartCommand() will
9765 // be called.
9766 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009767 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9768 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009769 }
9770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009771 sendServiceArgsLocked(r, true);
9772 }
9773
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009774 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9775 boolean allowCancel) {
9776 boolean canceled = false;
9777
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009778 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009779 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009780 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009781
Dianne Hackborn070783f2010-12-29 16:46:28 -08009782 if ((r.serviceInfo.applicationInfo.flags
9783 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9784 minDuration /= 4;
9785 }
9786
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009787 // Any delivered but not yet finished starts should be put back
9788 // on the pending list.
9789 final int N = r.deliveredStarts.size();
9790 if (N > 0) {
9791 for (int i=N-1; i>=0; i--) {
9792 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009793 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009794 if (si.intent == null) {
9795 // We'll generate this again if needed.
9796 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9797 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9798 r.pendingStarts.add(0, si);
9799 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9800 dur *= 2;
9801 if (minDuration < dur) minDuration = dur;
9802 if (resetTime < dur) resetTime = dur;
9803 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009804 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009805 + r.name);
9806 canceled = true;
9807 }
9808 }
9809 r.deliveredStarts.clear();
9810 }
9811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009812 r.totalRestartCount++;
9813 if (r.restartDelay == 0) {
9814 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009815 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816 } else {
9817 // If it has been a "reasonably long time" since the service
9818 // was started, then reset our restart duration back to
9819 // the beginning, so we don't infinitely increase the duration
9820 // on a service that just occasionally gets killed (which is
9821 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009822 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009823 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009824 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009825 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009826 if ((r.serviceInfo.applicationInfo.flags
9827 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9828 // Services in peristent processes will restart much more
9829 // quickly, since they are pretty important. (Think SystemUI).
9830 r.restartDelay += minDuration/2;
9831 } else {
9832 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9833 if (r.restartDelay < minDuration) {
9834 r.restartDelay = minDuration;
9835 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009837 }
9838 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009839
9840 r.nextRestartTime = now + r.restartDelay;
9841
9842 // Make sure that we don't end up restarting a bunch of services
9843 // all at the same time.
9844 boolean repeat;
9845 do {
9846 repeat = false;
9847 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9848 ServiceRecord r2 = mRestartingServices.get(i);
9849 if (r2 != r && r.nextRestartTime
9850 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9851 && r.nextRestartTime
9852 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9853 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9854 r.restartDelay = r.nextRestartTime - now;
9855 repeat = true;
9856 break;
9857 }
9858 }
9859 } while (repeat);
9860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009861 if (!mRestartingServices.contains(r)) {
9862 mRestartingServices.add(r);
9863 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009864
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009865 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009867 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009868 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009869 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009870 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009871 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009872 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009873 r.shortName, r.restartDelay);
9874
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009875 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009876 }
9877
9878 final void performServiceRestartLocked(ServiceRecord r) {
9879 if (!mRestartingServices.contains(r)) {
9880 return;
9881 }
9882 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9883 }
9884
9885 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9886 if (r.restartDelay == 0) {
9887 return false;
9888 }
9889 r.resetRestartCounter();
9890 mRestartingServices.remove(r);
9891 mHandler.removeCallbacks(r.restarter);
9892 return true;
9893 }
9894
9895 private final boolean bringUpServiceLocked(ServiceRecord r,
9896 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009897 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009898 //r.dump(" ");
9899
Dianne Hackborn36124872009-10-08 16:22:03 -07009900 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009901 sendServiceArgsLocked(r, false);
9902 return true;
9903 }
9904
9905 if (!whileRestarting && r.restartDelay > 0) {
9906 // If waiting for a restart, then do nothing.
9907 return true;
9908 }
9909
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009910 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009911
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009912 // We are now bringing the service up, so no longer in the
9913 // restarting state.
9914 mRestartingServices.remove(r);
9915
Dianne Hackborne7f97212011-02-24 14:40:20 -08009916 // Service is now being launched, its package can't be stopped.
9917 try {
9918 AppGlobals.getPackageManager().setPackageStoppedState(
9919 r.packageName, false);
9920 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009921 } catch (IllegalArgumentException e) {
9922 Slog.w(TAG, "Failed trying to unstop package "
9923 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009924 }
9925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009926 final String appName = r.processName;
9927 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9928 if (app != null && app.thread != null) {
9929 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -07009930 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009931 realStartServiceLocked(r, app);
9932 return true;
9933 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009934 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009935 }
9936
9937 // If a dead object exception was thrown -- fall through to
9938 // restart the application.
9939 }
9940
Dianne Hackborn36124872009-10-08 16:22:03 -07009941 // Not running -- get it started, and enqueue this service record
9942 // to be executed when the app comes up.
9943 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
9944 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009945 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -07009946 + r.appInfo.packageName + "/"
9947 + r.appInfo.uid + " for service "
9948 + r.intent.getIntent() + ": process is bad");
9949 bringDownServiceLocked(r, true);
9950 return false;
9951 }
9952
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009953 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009954 mPendingServices.add(r);
9955 }
Dianne Hackborn36124872009-10-08 16:22:03 -07009956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009957 return true;
9958 }
9959
9960 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009961 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009962 //r.dump(" ");
9963
9964 // Does it still need to run?
9965 if (!force && r.startRequested) {
9966 return;
9967 }
9968 if (r.connections.size() > 0) {
9969 if (!force) {
9970 // XXX should probably keep a count of the number of auto-create
9971 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009972 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009973 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009974 ArrayList<ConnectionRecord> cr = it.next();
9975 for (int i=0; i<cr.size(); i++) {
9976 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
9977 return;
9978 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009979 }
9980 }
9981 }
9982
9983 // Report to all of the connections that the service is no longer
9984 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009985 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009986 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009987 ArrayList<ConnectionRecord> c = it.next();
9988 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009989 ConnectionRecord cr = c.get(i);
9990 // There is still a connection to the service that is
9991 // being brought down. Mark it as dead.
9992 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009993 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009994 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009995 } catch (Exception e) {
9996 Slog.w(TAG, "Failure disconnecting service " + r.name +
9997 " to connection " + c.get(i).conn.asBinder() +
9998 " (in " + c.get(i).binding.client.processName + ")", e);
9999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010000 }
10001 }
10002 }
10003
10004 // Tell the service that it has been unbound.
10005 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10006 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10007 while (it.hasNext()) {
10008 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010009 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010010 + ": hasBound=" + ibr.hasBound);
10011 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10012 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010013 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010014 updateOomAdjLocked(r.app);
10015 ibr.hasBound = false;
10016 r.app.thread.scheduleUnbindService(r,
10017 ibr.intent.getIntent());
10018 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010019 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010020 + r.shortName, e);
10021 serviceDoneExecutingLocked(r, true);
10022 }
10023 }
10024 }
10025 }
10026
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010027 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010028 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010029 System.identityHashCode(r), r.shortName,
10030 (r.app != null) ? r.app.pid : -1);
10031
10032 mServices.remove(r.name);
10033 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010034 r.totalRestartCount = 0;
10035 unscheduleServiceRestartLocked(r);
10036
10037 // Also make sure it is not on the pending list.
10038 int N = mPendingServices.size();
10039 for (int i=0; i<N; i++) {
10040 if (mPendingServices.get(i) == r) {
10041 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010042 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043 i--;
10044 N--;
10045 }
10046 }
10047
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010048 r.cancelNotification();
10049 r.isForeground = false;
10050 r.foregroundId = 0;
10051 r.foregroundNoti = null;
10052
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010053 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010054 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010055 r.pendingStarts.clear();
10056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010057 if (r.app != null) {
10058 synchronized (r.stats.getBatteryStats()) {
10059 r.stats.stopLaunchedLocked();
10060 }
10061 r.app.services.remove(r);
10062 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010063 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010064 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 mStoppingServices.add(r);
10066 updateOomAdjLocked(r.app);
10067 r.app.thread.scheduleStopService(r);
10068 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010069 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 + r.shortName, e);
10071 serviceDoneExecutingLocked(r, true);
10072 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010073 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010074 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010075 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010076 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010077 }
10078 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010079 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010080 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010081 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010082
10083 if (r.bindings.size() > 0) {
10084 r.bindings.clear();
10085 }
10086
10087 if (r.restarter instanceof ServiceRestarter) {
10088 ((ServiceRestarter)r.restarter).setService(null);
10089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010090 }
10091
10092 ComponentName startServiceLocked(IApplicationThread caller,
10093 Intent service, String resolvedType,
10094 int callingPid, int callingUid) {
10095 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010096 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010097 + " type=" + resolvedType + " args=" + service.getExtras());
10098
10099 if (caller != null) {
10100 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10101 if (callerApp == null) {
10102 throw new SecurityException(
10103 "Unable to find app for caller " + caller
10104 + " (pid=" + Binder.getCallingPid()
10105 + ") when starting service " + service);
10106 }
10107 }
10108
10109 ServiceLookupResult res =
10110 retrieveServiceLocked(service, resolvedType,
10111 callingPid, callingUid);
10112 if (res == null) {
10113 return null;
10114 }
10115 if (res.record == null) {
10116 return new ComponentName("!", res.permission != null
10117 ? res.permission : "private to package");
10118 }
10119 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010120 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10121 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010122 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010123 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124 }
10125 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010126 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010127 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010128 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 r.lastActivity = SystemClock.uptimeMillis();
10130 synchronized (r.stats.getBatteryStats()) {
10131 r.stats.startRunningLocked();
10132 }
10133 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10134 return new ComponentName("!", "Service process is bad");
10135 }
10136 return r.name;
10137 }
10138 }
10139
10140 public ComponentName startService(IApplicationThread caller, Intent service,
10141 String resolvedType) {
10142 // Refuse possible leaked file descriptors
10143 if (service != null && service.hasFileDescriptors() == true) {
10144 throw new IllegalArgumentException("File descriptors passed in Intent");
10145 }
10146
10147 synchronized(this) {
10148 final int callingPid = Binder.getCallingPid();
10149 final int callingUid = Binder.getCallingUid();
10150 final long origId = Binder.clearCallingIdentity();
10151 ComponentName res = startServiceLocked(caller, service,
10152 resolvedType, callingPid, callingUid);
10153 Binder.restoreCallingIdentity(origId);
10154 return res;
10155 }
10156 }
10157
10158 ComponentName startServiceInPackage(int uid,
10159 Intent service, String resolvedType) {
10160 synchronized(this) {
10161 final long origId = Binder.clearCallingIdentity();
10162 ComponentName res = startServiceLocked(null, service,
10163 resolvedType, -1, uid);
10164 Binder.restoreCallingIdentity(origId);
10165 return res;
10166 }
10167 }
10168
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010169 private void stopServiceLocked(ServiceRecord service) {
10170 synchronized (service.stats.getBatteryStats()) {
10171 service.stats.stopRunningLocked();
10172 }
10173 service.startRequested = false;
10174 service.callStart = false;
10175 bringDownServiceLocked(service, false);
10176 }
10177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010178 public int stopService(IApplicationThread caller, Intent service,
10179 String resolvedType) {
10180 // Refuse possible leaked file descriptors
10181 if (service != null && service.hasFileDescriptors() == true) {
10182 throw new IllegalArgumentException("File descriptors passed in Intent");
10183 }
10184
10185 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010186 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010187 + " type=" + resolvedType);
10188
10189 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10190 if (caller != null && callerApp == null) {
10191 throw new SecurityException(
10192 "Unable to find app for caller " + caller
10193 + " (pid=" + Binder.getCallingPid()
10194 + ") when stopping service " + service);
10195 }
10196
10197 // If this service is active, make sure it is stopped.
10198 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10199 if (r != null) {
10200 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010201 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010202 try {
10203 stopServiceLocked(r.record);
10204 } finally {
10205 Binder.restoreCallingIdentity(origId);
10206 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010207 return 1;
10208 }
10209 return -1;
10210 }
10211 }
10212
10213 return 0;
10214 }
10215
10216 public IBinder peekService(Intent service, String resolvedType) {
10217 // Refuse possible leaked file descriptors
10218 if (service != null && service.hasFileDescriptors() == true) {
10219 throw new IllegalArgumentException("File descriptors passed in Intent");
10220 }
10221
10222 IBinder ret = null;
10223
10224 synchronized(this) {
10225 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10226
10227 if (r != null) {
10228 // r.record is null if findServiceLocked() failed the caller permission check
10229 if (r.record == null) {
10230 throw new SecurityException(
10231 "Permission Denial: Accessing service " + r.record.name
10232 + " from pid=" + Binder.getCallingPid()
10233 + ", uid=" + Binder.getCallingUid()
10234 + " requires " + r.permission);
10235 }
10236 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10237 if (ib != null) {
10238 ret = ib.binder;
10239 }
10240 }
10241 }
10242
10243 return ret;
10244 }
10245
10246 public boolean stopServiceToken(ComponentName className, IBinder token,
10247 int startId) {
10248 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010249 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010250 + " " + token + " startId=" + startId);
10251 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010252 if (r != null) {
10253 if (startId >= 0) {
10254 // Asked to only stop if done with all work. Note that
10255 // to avoid leaks, we will take this as dropping all
10256 // start items up to and including this one.
10257 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10258 if (si != null) {
10259 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010260 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10261 cur.removeUriPermissionsLocked();
10262 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010263 break;
10264 }
10265 }
10266 }
10267
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010268 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010269 return false;
10270 }
10271
10272 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010273 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010274 + " is last, but have " + r.deliveredStarts.size()
10275 + " remaining args");
10276 }
10277 }
10278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010279 synchronized (r.stats.getBatteryStats()) {
10280 r.stats.stopRunningLocked();
10281 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010282 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010283 }
10284 final long origId = Binder.clearCallingIdentity();
10285 bringDownServiceLocked(r, false);
10286 Binder.restoreCallingIdentity(origId);
10287 return true;
10288 }
10289 }
10290 return false;
10291 }
10292
10293 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010294 int id, Notification notification, boolean removeNotification) {
10295 final long origId = Binder.clearCallingIdentity();
10296 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010297 synchronized(this) {
10298 ServiceRecord r = findServiceLocked(className, token);
10299 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010300 if (id != 0) {
10301 if (notification == null) {
10302 throw new IllegalArgumentException("null notification");
10303 }
10304 if (r.foregroundId != id) {
10305 r.cancelNotification();
10306 r.foregroundId = id;
10307 }
10308 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10309 r.foregroundNoti = notification;
10310 r.isForeground = true;
10311 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 if (r.app != null) {
10313 updateServiceForegroundLocked(r.app, true);
10314 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010315 } else {
10316 if (r.isForeground) {
10317 r.isForeground = false;
10318 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010319 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010320 updateServiceForegroundLocked(r.app, true);
10321 }
10322 }
10323 if (removeNotification) {
10324 r.cancelNotification();
10325 r.foregroundId = 0;
10326 r.foregroundNoti = null;
10327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010328 }
10329 }
10330 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010331 } finally {
10332 Binder.restoreCallingIdentity(origId);
10333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010334 }
10335
10336 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10337 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010338 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010339 if (sr.isForeground) {
10340 anyForeground = true;
10341 break;
10342 }
10343 }
10344 if (anyForeground != proc.foregroundServices) {
10345 proc.foregroundServices = anyForeground;
10346 if (oomAdj) {
10347 updateOomAdjLocked();
10348 }
10349 }
10350 }
10351
10352 public int bindService(IApplicationThread caller, IBinder token,
10353 Intent service, String resolvedType,
10354 IServiceConnection connection, int flags) {
10355 // Refuse possible leaked file descriptors
10356 if (service != null && service.hasFileDescriptors() == true) {
10357 throw new IllegalArgumentException("File descriptors passed in Intent");
10358 }
10359
10360 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010361 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010362 + " type=" + resolvedType + " conn=" + connection.asBinder()
10363 + " flags=0x" + Integer.toHexString(flags));
10364 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10365 if (callerApp == null) {
10366 throw new SecurityException(
10367 "Unable to find app for caller " + caller
10368 + " (pid=" + Binder.getCallingPid()
10369 + ") when binding service " + service);
10370 }
10371
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010372 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010373 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010374 activity = mMainStack.isInStackLocked(token);
10375 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010376 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010377 return 0;
10378 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 }
10380
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010381 int clientLabel = 0;
10382 PendingIntent clientIntent = null;
10383
10384 if (callerApp.info.uid == Process.SYSTEM_UID) {
10385 // Hacky kind of thing -- allow system stuff to tell us
10386 // what they are, so we can report this elsewhere for
10387 // others to know why certain services are running.
10388 try {
10389 clientIntent = (PendingIntent)service.getParcelableExtra(
10390 Intent.EXTRA_CLIENT_INTENT);
10391 } catch (RuntimeException e) {
10392 }
10393 if (clientIntent != null) {
10394 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10395 if (clientLabel != 0) {
10396 // There are no useful extras in the intent, trash them.
10397 // System code calling with this stuff just needs to know
10398 // this will happen.
10399 service = service.cloneFilter();
10400 }
10401 }
10402 }
10403
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010404 ServiceLookupResult res =
10405 retrieveServiceLocked(service, resolvedType,
10406 Binder.getCallingPid(), Binder.getCallingUid());
10407 if (res == null) {
10408 return 0;
10409 }
10410 if (res.record == null) {
10411 return -1;
10412 }
10413 ServiceRecord s = res.record;
10414
10415 final long origId = Binder.clearCallingIdentity();
10416
10417 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010418 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010419 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010420 }
10421
10422 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10423 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010424 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010425
10426 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010427 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10428 if (clist == null) {
10429 clist = new ArrayList<ConnectionRecord>();
10430 s.connections.put(binder, clist);
10431 }
10432 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010433 b.connections.add(c);
10434 if (activity != null) {
10435 if (activity.connections == null) {
10436 activity.connections = new HashSet<ConnectionRecord>();
10437 }
10438 activity.connections.add(c);
10439 }
10440 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010441 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10442 b.client.hasAboveClient = true;
10443 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010444 clist = mServiceConnections.get(binder);
10445 if (clist == null) {
10446 clist = new ArrayList<ConnectionRecord>();
10447 mServiceConnections.put(binder, clist);
10448 }
10449 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010450
10451 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10452 s.lastActivity = SystemClock.uptimeMillis();
10453 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10454 return 0;
10455 }
10456 }
10457
10458 if (s.app != null) {
10459 // This could have made the service more important.
10460 updateOomAdjLocked(s.app);
10461 }
10462
Joe Onorato8a9b2202010-02-26 18:56:32 -080010463 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010464 + ": received=" + b.intent.received
10465 + " apps=" + b.intent.apps.size()
10466 + " doRebind=" + b.intent.doRebind);
10467
10468 if (s.app != null && b.intent.received) {
10469 // Service is already running, so we can immediately
10470 // publish the connection.
10471 try {
10472 c.conn.connected(s.name, b.intent.binder);
10473 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010474 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010475 + " to connection " + c.conn.asBinder()
10476 + " (in " + c.binding.client.processName + ")", e);
10477 }
10478
10479 // If this is the first app connected back to this binding,
10480 // and the service had previously asked to be told when
10481 // rebound, then do so.
10482 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10483 requestServiceBindingLocked(s, b.intent, true);
10484 }
10485 } else if (!b.intent.requested) {
10486 requestServiceBindingLocked(s, b.intent, false);
10487 }
10488
10489 Binder.restoreCallingIdentity(origId);
10490 }
10491
10492 return 1;
10493 }
10494
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010495 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010496 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010497 IBinder binder = c.conn.asBinder();
10498 AppBindRecord b = c.binding;
10499 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010500 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10501 if (clist != null) {
10502 clist.remove(c);
10503 if (clist.size() == 0) {
10504 s.connections.remove(binder);
10505 }
10506 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010507 b.connections.remove(c);
10508 if (c.activity != null && c.activity != skipAct) {
10509 if (c.activity.connections != null) {
10510 c.activity.connections.remove(c);
10511 }
10512 }
10513 if (b.client != skipApp) {
10514 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010515 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10516 b.client.updateHasAboveClientLocked();
10517 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010518 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010519 clist = mServiceConnections.get(binder);
10520 if (clist != null) {
10521 clist.remove(c);
10522 if (clist.size() == 0) {
10523 mServiceConnections.remove(binder);
10524 }
10525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010526
10527 if (b.connections.size() == 0) {
10528 b.intent.apps.remove(b.client);
10529 }
10530
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010531 if (!c.serviceDead) {
10532 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10533 + ": shouldUnbind=" + b.intent.hasBound);
10534 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10535 && b.intent.hasBound) {
10536 try {
10537 bumpServiceExecutingLocked(s, "unbind");
10538 updateOomAdjLocked(s.app);
10539 b.intent.hasBound = false;
10540 // Assume the client doesn't want to know about a rebind;
10541 // we will deal with that later if it asks for one.
10542 b.intent.doRebind = false;
10543 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10544 } catch (Exception e) {
10545 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10546 serviceDoneExecutingLocked(s, true);
10547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010549
10550 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10551 bringDownServiceLocked(s, false);
10552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010553 }
10554 }
10555
10556 public boolean unbindService(IServiceConnection connection) {
10557 synchronized (this) {
10558 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010559 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010560 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10561 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010562 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010563 + connection.asBinder());
10564 return false;
10565 }
10566
10567 final long origId = Binder.clearCallingIdentity();
10568
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010569 while (clist.size() > 0) {
10570 ConnectionRecord r = clist.get(0);
10571 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010572
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010573 if (r.binding.service.app != null) {
10574 // This could have made the service less important.
10575 updateOomAdjLocked(r.binding.service.app);
10576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010577 }
10578
10579 Binder.restoreCallingIdentity(origId);
10580 }
10581
10582 return true;
10583 }
10584
10585 public void publishService(IBinder token, Intent intent, IBinder service) {
10586 // Refuse possible leaked file descriptors
10587 if (intent != null && intent.hasFileDescriptors() == true) {
10588 throw new IllegalArgumentException("File descriptors passed in Intent");
10589 }
10590
10591 synchronized(this) {
10592 if (!(token instanceof ServiceRecord)) {
10593 throw new IllegalArgumentException("Invalid service token");
10594 }
10595 ServiceRecord r = (ServiceRecord)token;
10596
10597 final long origId = Binder.clearCallingIdentity();
10598
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010599 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010600 + " " + intent + ": " + service);
10601 if (r != null) {
10602 Intent.FilterComparison filter
10603 = new Intent.FilterComparison(intent);
10604 IntentBindRecord b = r.bindings.get(filter);
10605 if (b != null && !b.received) {
10606 b.binder = service;
10607 b.requested = true;
10608 b.received = true;
10609 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010610 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010611 = r.connections.values().iterator();
10612 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010613 ArrayList<ConnectionRecord> clist = it.next();
10614 for (int i=0; i<clist.size(); i++) {
10615 ConnectionRecord c = clist.get(i);
10616 if (!filter.equals(c.binding.intent.intent)) {
10617 if (DEBUG_SERVICE) Slog.v(
10618 TAG, "Not publishing to: " + c);
10619 if (DEBUG_SERVICE) Slog.v(
10620 TAG, "Bound intent: " + c.binding.intent.intent);
10621 if (DEBUG_SERVICE) Slog.v(
10622 TAG, "Published intent: " + intent);
10623 continue;
10624 }
10625 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10626 try {
10627 c.conn.connected(r.name, service);
10628 } catch (Exception e) {
10629 Slog.w(TAG, "Failure sending service " + r.name +
10630 " to connection " + c.conn.asBinder() +
10631 " (in " + c.binding.client.processName + ")", e);
10632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010633 }
10634 }
10635 }
10636 }
10637
10638 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10639
10640 Binder.restoreCallingIdentity(origId);
10641 }
10642 }
10643 }
10644
10645 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10646 // Refuse possible leaked file descriptors
10647 if (intent != null && intent.hasFileDescriptors() == true) {
10648 throw new IllegalArgumentException("File descriptors passed in Intent");
10649 }
10650
10651 synchronized(this) {
10652 if (!(token instanceof ServiceRecord)) {
10653 throw new IllegalArgumentException("Invalid service token");
10654 }
10655 ServiceRecord r = (ServiceRecord)token;
10656
10657 final long origId = Binder.clearCallingIdentity();
10658
10659 if (r != null) {
10660 Intent.FilterComparison filter
10661 = new Intent.FilterComparison(intent);
10662 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010663 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 + " at " + b + ": apps="
10665 + (b != null ? b.apps.size() : 0));
10666 if (b != null) {
10667 if (b.apps.size() > 0) {
10668 // Applications have already bound since the last
10669 // unbind, so just rebind right here.
10670 requestServiceBindingLocked(r, b, true);
10671 } else {
10672 // Note to tell the service the next time there is
10673 // a new client.
10674 b.doRebind = true;
10675 }
10676 }
10677
10678 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10679
10680 Binder.restoreCallingIdentity(origId);
10681 }
10682 }
10683 }
10684
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010685 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010686 synchronized(this) {
10687 if (!(token instanceof ServiceRecord)) {
10688 throw new IllegalArgumentException("Invalid service token");
10689 }
10690 ServiceRecord r = (ServiceRecord)token;
10691 boolean inStopping = mStoppingServices.contains(token);
10692 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010693 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010694 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010695 + " with incorrect token: given " + token
10696 + ", expected " + r);
10697 return;
10698 }
10699
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010700 if (type == 1) {
10701 // This is a call from a service start... take care of
10702 // book-keeping.
10703 r.callStart = true;
10704 switch (res) {
10705 case Service.START_STICKY_COMPATIBILITY:
10706 case Service.START_STICKY: {
10707 // We are done with the associated start arguments.
10708 r.findDeliveredStart(startId, true);
10709 // Don't stop if killed.
10710 r.stopIfKilled = false;
10711 break;
10712 }
10713 case Service.START_NOT_STICKY: {
10714 // We are done with the associated start arguments.
10715 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010716 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010717 // There is no more work, and this service
10718 // doesn't want to hang around if killed.
10719 r.stopIfKilled = true;
10720 }
10721 break;
10722 }
10723 case Service.START_REDELIVER_INTENT: {
10724 // We'll keep this item until they explicitly
10725 // call stop for it, but keep track of the fact
10726 // that it was delivered.
10727 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10728 if (si != null) {
10729 si.deliveryCount = 0;
10730 si.doneExecutingCount++;
10731 // Don't stop if killed.
10732 r.stopIfKilled = true;
10733 }
10734 break;
10735 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010736 case Service.START_TASK_REMOVED_COMPLETE: {
10737 // Special processing for onTaskRemoved(). Don't
10738 // impact normal onStartCommand() processing.
10739 r.findDeliveredStart(startId, true);
10740 break;
10741 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010742 default:
10743 throw new IllegalArgumentException(
10744 "Unknown service start result: " + res);
10745 }
10746 if (res == Service.START_STICKY_COMPATIBILITY) {
10747 r.callStart = false;
10748 }
10749 }
10750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010751 final long origId = Binder.clearCallingIdentity();
10752 serviceDoneExecutingLocked(r, inStopping);
10753 Binder.restoreCallingIdentity(origId);
10754 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010755 Slog.w(TAG, "Done executing unknown service from pid "
10756 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010757 }
10758 }
10759 }
10760
10761 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010762 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10763 + ": nesting=" + r.executeNesting
10764 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010765 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010766 r.executeNesting--;
10767 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010768 if (DEBUG_SERVICE) Slog.v(TAG,
10769 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010770 r.app.executingServices.remove(r);
10771 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010772 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10773 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010774 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10775 }
10776 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010777 if (DEBUG_SERVICE) Slog.v(TAG,
10778 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010779 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010780 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 }
10782 updateOomAdjLocked(r.app);
10783 }
10784 }
10785
10786 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010787 String anrMessage = null;
10788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010789 synchronized(this) {
10790 if (proc.executingServices.size() == 0 || proc.thread == null) {
10791 return;
10792 }
10793 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10794 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10795 ServiceRecord timeout = null;
10796 long nextTime = 0;
10797 while (it.hasNext()) {
10798 ServiceRecord sr = it.next();
10799 if (sr.executingStart < maxTime) {
10800 timeout = sr;
10801 break;
10802 }
10803 if (sr.executingStart > nextTime) {
10804 nextTime = sr.executingStart;
10805 }
10806 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010807 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010808 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010809 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010810 } else {
10811 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10812 msg.obj = proc;
10813 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10814 }
10815 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010816
10817 if (anrMessage != null) {
10818 appNotResponding(proc, null, null, anrMessage);
10819 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010820 }
10821
10822 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010823 // BACKUP AND RESTORE
10824 // =========================================================
10825
10826 // Cause the target app to be launched if necessary and its backup agent
10827 // instantiated. The backup agent will invoke backupAgentCreated() on the
10828 // activity manager to announce its creation.
10829 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010830 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010831 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10832
10833 synchronized(this) {
10834 // !!! TODO: currently no check here that we're already bound
10835 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10836 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10837 synchronized (stats) {
10838 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10839 }
10840
Dianne Hackborne7f97212011-02-24 14:40:20 -080010841 // Backup agent is now in use, its package can't be stopped.
10842 try {
10843 AppGlobals.getPackageManager().setPackageStoppedState(
10844 app.packageName, false);
10845 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010846 } catch (IllegalArgumentException e) {
10847 Slog.w(TAG, "Failed trying to unstop package "
10848 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010849 }
10850
Christopher Tate181fafa2009-05-14 11:12:14 -070010851 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010852 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10853 ? new ComponentName(app.packageName, app.backupAgentName)
10854 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010855 // startProcessLocked() returns existing proc's record if it's already running
10856 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010857 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010858 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010859 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010860 return false;
10861 }
10862
10863 r.app = proc;
10864 mBackupTarget = r;
10865 mBackupAppName = app.packageName;
10866
Christopher Tate6fa95972009-06-05 18:43:55 -070010867 // Try not to kill the process during backup
10868 updateOomAdjLocked(proc);
10869
Christopher Tate181fafa2009-05-14 11:12:14 -070010870 // If the process is already attached, schedule the creation of the backup agent now.
10871 // If it is not yet live, this will be done when it attaches to the framework.
10872 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010873 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010874 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010875 proc.thread.scheduleCreateBackupAgent(app,
10876 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010877 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010878 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010879 }
10880 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010881 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010882 }
10883 // Invariants: at this point, the target app process exists and the application
10884 // is either already running or in the process of coming up. mBackupTarget and
10885 // mBackupAppName describe the app, so that when it binds back to the AM we
10886 // know that it's scheduled for a backup-agent operation.
10887 }
10888
10889 return true;
10890 }
10891
10892 // A backup agent has just come up
10893 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010894 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010895 + " = " + agent);
10896
10897 synchronized(this) {
10898 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010899 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010900 return;
10901 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010902 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010903
Dianne Hackborn06740692010-09-22 22:46:21 -070010904 long oldIdent = Binder.clearCallingIdentity();
10905 try {
10906 IBackupManager bm = IBackupManager.Stub.asInterface(
10907 ServiceManager.getService(Context.BACKUP_SERVICE));
10908 bm.agentConnected(agentPackageName, agent);
10909 } catch (RemoteException e) {
10910 // can't happen; the backup manager service is local
10911 } catch (Exception e) {
10912 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10913 e.printStackTrace();
10914 } finally {
10915 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010916 }
10917 }
10918
10919 // done with this agent
10920 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010921 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010922 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010923 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010924 return;
10925 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010926
10927 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010928 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010929 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010930 return;
10931 }
10932
Christopher Tate181fafa2009-05-14 11:12:14 -070010933 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010934 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010935 return;
10936 }
10937
Christopher Tate6fa95972009-06-05 18:43:55 -070010938 ProcessRecord proc = mBackupTarget.app;
10939 mBackupTarget = null;
10940 mBackupAppName = null;
10941
10942 // Not backing this app up any more; reset its OOM adjustment
10943 updateOomAdjLocked(proc);
10944
Christopher Tatec7b31e32009-06-10 15:49:30 -070010945 // If the app crashed during backup, 'thread' will be null here
10946 if (proc.thread != null) {
10947 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010948 proc.thread.scheduleDestroyBackupAgent(appInfo,
10949 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010950 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010951 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010952 e.printStackTrace();
10953 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010954 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010955 }
10956 }
10957 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010958 // BROADCASTS
10959 // =========================================================
10960
Josh Bartel7f208742010-02-25 11:01:44 -060010961 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010962 List cur) {
10963 final ContentResolver resolver = mContext.getContentResolver();
10964 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
10965 if (list == null) {
10966 return cur;
10967 }
10968 int N = list.size();
10969 for (int i=0; i<N; i++) {
10970 Intent intent = list.get(i);
10971 if (filter.match(resolver, intent, true, TAG) >= 0) {
10972 if (cur == null) {
10973 cur = new ArrayList<Intent>();
10974 }
10975 cur.add(intent);
10976 }
10977 }
10978 return cur;
10979 }
10980
10981 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010982 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010983 + mBroadcastsScheduled);
10984
10985 if (mBroadcastsScheduled) {
10986 return;
10987 }
10988 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
10989 mBroadcastsScheduled = true;
10990 }
10991
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010992 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010993 IIntentReceiver receiver, IntentFilter filter, String permission) {
10994 synchronized(this) {
10995 ProcessRecord callerApp = null;
10996 if (caller != null) {
10997 callerApp = getRecordForAppLocked(caller);
10998 if (callerApp == null) {
10999 throw new SecurityException(
11000 "Unable to find app for caller " + caller
11001 + " (pid=" + Binder.getCallingPid()
11002 + ") when registering receiver " + receiver);
11003 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011004 if (callerApp.info.uid != Process.SYSTEM_UID &&
11005 !callerApp.pkgList.contains(callerPackage)) {
11006 throw new SecurityException("Given caller package " + callerPackage
11007 + " is not running in process " + callerApp);
11008 }
11009 } else {
11010 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011011 }
11012
11013 List allSticky = null;
11014
11015 // Look for any matching sticky broadcasts...
11016 Iterator actions = filter.actionsIterator();
11017 if (actions != null) {
11018 while (actions.hasNext()) {
11019 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011020 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011021 }
11022 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011023 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 }
11025
11026 // The first sticky in the list is returned directly back to
11027 // the client.
11028 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11029
Joe Onorato8a9b2202010-02-26 18:56:32 -080011030 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011031 + ": " + sticky);
11032
11033 if (receiver == null) {
11034 return sticky;
11035 }
11036
11037 ReceiverList rl
11038 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11039 if (rl == null) {
11040 rl = new ReceiverList(this, callerApp,
11041 Binder.getCallingPid(),
11042 Binder.getCallingUid(), receiver);
11043 if (rl.app != null) {
11044 rl.app.receivers.add(rl);
11045 } else {
11046 try {
11047 receiver.asBinder().linkToDeath(rl, 0);
11048 } catch (RemoteException e) {
11049 return sticky;
11050 }
11051 rl.linkedToDeath = true;
11052 }
11053 mRegisteredReceivers.put(receiver.asBinder(), rl);
11054 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011055 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011056 rl.add(bf);
11057 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011058 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011059 }
11060 mReceiverResolver.addFilter(bf);
11061
11062 // Enqueue broadcasts for all existing stickies that match
11063 // this filter.
11064 if (allSticky != null) {
11065 ArrayList receivers = new ArrayList();
11066 receivers.add(bf);
11067
11068 int N = allSticky.size();
11069 for (int i=0; i<N; i++) {
11070 Intent intent = (Intent)allSticky.get(i);
11071 BroadcastRecord r = new BroadcastRecord(intent, null,
11072 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011073 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011074 if (mParallelBroadcasts.size() == 0) {
11075 scheduleBroadcastsLocked();
11076 }
11077 mParallelBroadcasts.add(r);
11078 }
11079 }
11080
11081 return sticky;
11082 }
11083 }
11084
11085 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011086 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011087
11088 boolean doNext = false;
11089
11090 synchronized(this) {
11091 ReceiverList rl
11092 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11093 if (rl != null) {
11094 if (rl.curBroadcast != null) {
11095 BroadcastRecord r = rl.curBroadcast;
11096 doNext = finishReceiverLocked(
11097 receiver.asBinder(), r.resultCode, r.resultData,
11098 r.resultExtras, r.resultAbort, true);
11099 }
11100
11101 if (rl.app != null) {
11102 rl.app.receivers.remove(rl);
11103 }
11104 removeReceiverLocked(rl);
11105 if (rl.linkedToDeath) {
11106 rl.linkedToDeath = false;
11107 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11108 }
11109 }
11110 }
11111
11112 if (!doNext) {
11113 return;
11114 }
11115
11116 final long origId = Binder.clearCallingIdentity();
11117 processNextBroadcast(false);
11118 trimApplications();
11119 Binder.restoreCallingIdentity(origId);
11120 }
11121
11122 void removeReceiverLocked(ReceiverList rl) {
11123 mRegisteredReceivers.remove(rl.receiver.asBinder());
11124 int N = rl.size();
11125 for (int i=0; i<N; i++) {
11126 mReceiverResolver.removeFilter(rl.get(i));
11127 }
11128 }
11129
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011130 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11131 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11132 ProcessRecord r = mLruProcesses.get(i);
11133 if (r.thread != null) {
11134 try {
11135 r.thread.dispatchPackageBroadcast(cmd, packages);
11136 } catch (RemoteException ex) {
11137 }
11138 }
11139 }
11140 }
11141
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011142 private final int broadcastIntentLocked(ProcessRecord callerApp,
11143 String callerPackage, Intent intent, String resolvedType,
11144 IIntentReceiver resultTo, int resultCode, String resultData,
11145 Bundle map, String requiredPermission,
11146 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11147 intent = new Intent(intent);
11148
Dianne Hackborne7f97212011-02-24 14:40:20 -080011149 // By default broadcasts do not go to stopped apps.
11150 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11151
Joe Onorato8a9b2202010-02-26 18:56:32 -080011152 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011153 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11154 + " ordered=" + ordered);
11155 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011156 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011157 }
11158
11159 // Handle special intents: if this broadcast is from the package
11160 // manager about a package being removed, we need to remove all of
11161 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011162 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011163 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011164 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11165 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011166 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011167 || uidRemoved) {
11168 if (checkComponentPermission(
11169 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011170 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011171 == PackageManager.PERMISSION_GRANTED) {
11172 if (uidRemoved) {
11173 final Bundle intentExtras = intent.getExtras();
11174 final int uid = intentExtras != null
11175 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11176 if (uid >= 0) {
11177 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11178 synchronized (bs) {
11179 bs.removeUidStatsLocked(uid);
11180 }
11181 }
11182 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011183 // If resources are unvailble just force stop all
11184 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011185 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011186 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11187 if (list != null && (list.length > 0)) {
11188 for (String pkg : list) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011189 forceStopPackageLocked(pkg, -1, false, true, true);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011190 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011191 sendPackageBroadcastLocked(
11192 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011193 }
11194 } else {
11195 Uri data = intent.getData();
11196 String ssp;
11197 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11198 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11199 forceStopPackageLocked(ssp,
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080011200 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011201 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011202 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011203 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11204 new String[] {ssp});
11205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011206 }
11207 }
11208 }
11209 } else {
11210 String msg = "Permission Denial: " + intent.getAction()
11211 + " broadcast from " + callerPackage + " (pid=" + callingPid
11212 + ", uid=" + callingUid + ")"
11213 + " requires "
11214 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011215 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011216 throw new SecurityException(msg);
11217 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011218
11219 // Special case for adding a package: by default turn on compatibility
11220 // mode.
11221 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011222 Uri data = intent.getData();
11223 String ssp;
11224 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11225 mCompatModePackages.handlePackageAddedLocked(ssp,
11226 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011228 }
11229
11230 /*
11231 * If this is the time zone changed action, queue up a message that will reset the timezone
11232 * of all currently running processes. This message will get queued up before the broadcast
11233 * happens.
11234 */
11235 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11236 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11237 }
11238
Robert Greenwalt03595d02010-11-02 14:08:23 -070011239 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11240 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11241 }
11242
Robert Greenwalt434203a2010-10-11 16:00:27 -070011243 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11244 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11245 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11246 }
11247
Dianne Hackborn854060af2009-07-09 18:14:31 -070011248 /*
11249 * Prevent non-system code (defined here to be non-persistent
11250 * processes) from sending protected broadcasts.
11251 */
11252 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11253 || callingUid == Process.SHELL_UID || callingUid == 0) {
11254 // Always okay.
11255 } else if (callerApp == null || !callerApp.persistent) {
11256 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011257 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011258 intent.getAction())) {
11259 String msg = "Permission Denial: not allowed to send broadcast "
11260 + intent.getAction() + " from pid="
11261 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011262 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011263 throw new SecurityException(msg);
11264 }
11265 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011266 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011267 return BROADCAST_SUCCESS;
11268 }
11269 }
11270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011271 // Add to the sticky list if requested.
11272 if (sticky) {
11273 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11274 callingPid, callingUid)
11275 != PackageManager.PERMISSION_GRANTED) {
11276 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11277 + callingPid + ", uid=" + callingUid
11278 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011279 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011280 throw new SecurityException(msg);
11281 }
11282 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011283 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011284 + " and enforce permission " + requiredPermission);
11285 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11286 }
11287 if (intent.getComponent() != null) {
11288 throw new SecurityException(
11289 "Sticky broadcasts can't target a specific component");
11290 }
11291 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11292 if (list == null) {
11293 list = new ArrayList<Intent>();
11294 mStickyBroadcasts.put(intent.getAction(), list);
11295 }
11296 int N = list.size();
11297 int i;
11298 for (i=0; i<N; i++) {
11299 if (intent.filterEquals(list.get(i))) {
11300 // This sticky already exists, replace it.
11301 list.set(i, new Intent(intent));
11302 break;
11303 }
11304 }
11305 if (i >= N) {
11306 list.add(new Intent(intent));
11307 }
11308 }
11309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011310 // Figure out who all will receive this broadcast.
11311 List receivers = null;
11312 List<BroadcastFilter> registeredReceivers = null;
11313 try {
11314 if (intent.getComponent() != null) {
11315 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011316 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011317 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011318 if (ai != null) {
11319 receivers = new ArrayList();
11320 ResolveInfo ri = new ResolveInfo();
11321 ri.activityInfo = ai;
11322 receivers.add(ri);
11323 }
11324 } else {
11325 // Need to resolve the intent to interested receivers...
11326 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11327 == 0) {
11328 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011329 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011330 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011331 }
Mihai Preda074edef2009-05-18 17:13:31 +020011332 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011333 }
11334 } catch (RemoteException ex) {
11335 // pm is in same process, this will never happen.
11336 }
11337
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011338 final boolean replacePending =
11339 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11340
Joe Onorato8a9b2202010-02-26 18:56:32 -080011341 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011342 + " replacePending=" + replacePending);
11343
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011344 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11345 if (!ordered && NR > 0) {
11346 // If we are not serializing this broadcast, then send the
11347 // registered receivers separately so they don't wait for the
11348 // components to be launched.
11349 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11350 callerPackage, callingPid, callingUid, requiredPermission,
11351 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011352 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011353 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011354 TAG, "Enqueueing parallel broadcast " + r
11355 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011356 boolean replaced = false;
11357 if (replacePending) {
11358 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11359 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011360 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011361 "***** DROPPING PARALLEL: " + intent);
11362 mParallelBroadcasts.set(i, r);
11363 replaced = true;
11364 break;
11365 }
11366 }
11367 }
11368 if (!replaced) {
11369 mParallelBroadcasts.add(r);
11370 scheduleBroadcastsLocked();
11371 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011372 registeredReceivers = null;
11373 NR = 0;
11374 }
11375
11376 // Merge into one list.
11377 int ir = 0;
11378 if (receivers != null) {
11379 // A special case for PACKAGE_ADDED: do not allow the package
11380 // being added to see this broadcast. This prevents them from
11381 // using this as a back door to get run as soon as they are
11382 // installed. Maybe in the future we want to have a special install
11383 // broadcast or such for apps, but we'd like to deliberately make
11384 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011385 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011386 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11387 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11388 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011389 Uri data = intent.getData();
11390 if (data != null) {
11391 String pkgName = data.getSchemeSpecificPart();
11392 if (pkgName != null) {
11393 skipPackages = new String[] { pkgName };
11394 }
11395 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011396 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011397 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011398 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011399 if (skipPackages != null && (skipPackages.length > 0)) {
11400 for (String skipPackage : skipPackages) {
11401 if (skipPackage != null) {
11402 int NT = receivers.size();
11403 for (int it=0; it<NT; it++) {
11404 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11405 if (curt.activityInfo.packageName.equals(skipPackage)) {
11406 receivers.remove(it);
11407 it--;
11408 NT--;
11409 }
11410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011411 }
11412 }
11413 }
11414
11415 int NT = receivers != null ? receivers.size() : 0;
11416 int it = 0;
11417 ResolveInfo curt = null;
11418 BroadcastFilter curr = null;
11419 while (it < NT && ir < NR) {
11420 if (curt == null) {
11421 curt = (ResolveInfo)receivers.get(it);
11422 }
11423 if (curr == null) {
11424 curr = registeredReceivers.get(ir);
11425 }
11426 if (curr.getPriority() >= curt.priority) {
11427 // Insert this broadcast record into the final list.
11428 receivers.add(it, curr);
11429 ir++;
11430 curr = null;
11431 it++;
11432 NT++;
11433 } else {
11434 // Skip to the next ResolveInfo in the final list.
11435 it++;
11436 curt = null;
11437 }
11438 }
11439 }
11440 while (ir < NR) {
11441 if (receivers == null) {
11442 receivers = new ArrayList();
11443 }
11444 receivers.add(registeredReceivers.get(ir));
11445 ir++;
11446 }
11447
11448 if ((receivers != null && receivers.size() > 0)
11449 || resultTo != null) {
11450 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11451 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011452 receivers, resultTo, resultCode, resultData, map, ordered,
11453 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011454 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011455 TAG, "Enqueueing ordered broadcast " + r
11456 + ": prev had " + mOrderedBroadcasts.size());
11457 if (DEBUG_BROADCAST) {
11458 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011459 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011460 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011461 boolean replaced = false;
11462 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011463 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011464 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011465 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011466 "***** DROPPING ORDERED: " + intent);
11467 mOrderedBroadcasts.set(i, r);
11468 replaced = true;
11469 break;
11470 }
11471 }
11472 }
11473 if (!replaced) {
11474 mOrderedBroadcasts.add(r);
11475 scheduleBroadcastsLocked();
11476 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011477 }
11478
11479 return BROADCAST_SUCCESS;
11480 }
11481
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011482 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011483 // Refuse possible leaked file descriptors
11484 if (intent != null && intent.hasFileDescriptors() == true) {
11485 throw new IllegalArgumentException("File descriptors passed in Intent");
11486 }
11487
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011488 int flags = intent.getFlags();
11489
11490 if (!mProcessesReady) {
11491 // if the caller really truly claims to know what they're doing, go
11492 // ahead and allow the broadcast without launching any receivers
11493 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11494 intent = new Intent(intent);
11495 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11496 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11497 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11498 + " before boot completion");
11499 throw new IllegalStateException("Cannot broadcast before boot completed");
11500 }
11501 }
11502
11503 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11504 throw new IllegalArgumentException(
11505 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11506 }
11507
11508 return intent;
11509 }
11510
11511 public final int broadcastIntent(IApplicationThread caller,
11512 Intent intent, String resolvedType, IIntentReceiver resultTo,
11513 int resultCode, String resultData, Bundle map,
11514 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011515 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011516 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011518 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11519 final int callingPid = Binder.getCallingPid();
11520 final int callingUid = Binder.getCallingUid();
11521 final long origId = Binder.clearCallingIdentity();
11522 int res = broadcastIntentLocked(callerApp,
11523 callerApp != null ? callerApp.info.packageName : null,
11524 intent, resolvedType, resultTo,
11525 resultCode, resultData, map, requiredPermission, serialized,
11526 sticky, callingPid, callingUid);
11527 Binder.restoreCallingIdentity(origId);
11528 return res;
11529 }
11530 }
11531
11532 int broadcastIntentInPackage(String packageName, int uid,
11533 Intent intent, String resolvedType, IIntentReceiver resultTo,
11534 int resultCode, String resultData, Bundle map,
11535 String requiredPermission, boolean serialized, boolean sticky) {
11536 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011537 intent = verifyBroadcastLocked(intent);
11538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011539 final long origId = Binder.clearCallingIdentity();
11540 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11541 resultTo, resultCode, resultData, map, requiredPermission,
11542 serialized, sticky, -1, uid);
11543 Binder.restoreCallingIdentity(origId);
11544 return res;
11545 }
11546 }
11547
11548 public final void unbroadcastIntent(IApplicationThread caller,
11549 Intent intent) {
11550 // Refuse possible leaked file descriptors
11551 if (intent != null && intent.hasFileDescriptors() == true) {
11552 throw new IllegalArgumentException("File descriptors passed in Intent");
11553 }
11554
11555 synchronized(this) {
11556 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11557 != PackageManager.PERMISSION_GRANTED) {
11558 String msg = "Permission Denial: unbroadcastIntent() from pid="
11559 + Binder.getCallingPid()
11560 + ", uid=" + Binder.getCallingUid()
11561 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011562 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011563 throw new SecurityException(msg);
11564 }
11565 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11566 if (list != null) {
11567 int N = list.size();
11568 int i;
11569 for (i=0; i<N; i++) {
11570 if (intent.filterEquals(list.get(i))) {
11571 list.remove(i);
11572 break;
11573 }
11574 }
11575 }
11576 }
11577 }
11578
11579 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11580 String resultData, Bundle resultExtras, boolean resultAbort,
11581 boolean explicit) {
11582 if (mOrderedBroadcasts.size() == 0) {
11583 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011584 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011585 }
11586 return false;
11587 }
11588 BroadcastRecord r = mOrderedBroadcasts.get(0);
11589 if (r.receiver == null) {
11590 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011591 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011592 }
11593 return false;
11594 }
11595 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011596 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011597 return false;
11598 }
11599 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011600 r.state = BroadcastRecord.IDLE;
11601 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011602 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011603 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011604 }
11605 }
11606 r.receiver = null;
11607 r.intent.setComponent(null);
11608 if (r.curApp != null) {
11609 r.curApp.curReceiver = null;
11610 }
11611 if (r.curFilter != null) {
11612 r.curFilter.receiverList.curBroadcast = null;
11613 }
11614 r.curFilter = null;
11615 r.curApp = null;
11616 r.curComponent = null;
11617 r.curReceiver = null;
11618 mPendingBroadcast = null;
11619
11620 r.resultCode = resultCode;
11621 r.resultData = resultData;
11622 r.resultExtras = resultExtras;
11623 r.resultAbort = resultAbort;
11624
11625 // We will process the next receiver right now if this is finishing
11626 // an app receiver (which is always asynchronous) or after we have
11627 // come back from calling a receiver.
11628 return state == BroadcastRecord.APP_RECEIVE
11629 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11630 }
11631
11632 public void finishReceiver(IBinder who, int resultCode, String resultData,
11633 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011634 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011635
11636 // Refuse possible leaked file descriptors
11637 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11638 throw new IllegalArgumentException("File descriptors passed in Bundle");
11639 }
11640
11641 boolean doNext;
11642
11643 final long origId = Binder.clearCallingIdentity();
11644
11645 synchronized(this) {
11646 doNext = finishReceiverLocked(
11647 who, resultCode, resultData, resultExtras, resultAbort, true);
11648 }
11649
11650 if (doNext) {
11651 processNextBroadcast(false);
11652 }
11653 trimApplications();
11654
11655 Binder.restoreCallingIdentity(origId);
11656 }
11657
Jeff Brown4d94a762010-09-23 11:33:28 -070011658 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011659 if (r.nextReceiver > 0) {
11660 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11661 if (curReceiver instanceof BroadcastFilter) {
11662 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011663 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011664 System.identityHashCode(r),
11665 r.intent.getAction(),
11666 r.nextReceiver - 1,
11667 System.identityHashCode(bf));
11668 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011669 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011670 System.identityHashCode(r),
11671 r.intent.getAction(),
11672 r.nextReceiver - 1,
11673 ((ResolveInfo)curReceiver).toString());
11674 }
11675 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011676 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011677 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011678 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 System.identityHashCode(r),
11680 r.intent.getAction(),
11681 r.nextReceiver,
11682 "NONE");
11683 }
11684 }
11685
Jeff Brown4d94a762010-09-23 11:33:28 -070011686 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11687 if (! mPendingBroadcastTimeoutMessage) {
11688 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11689 mHandler.sendMessageAtTime(msg, timeoutTime);
11690 mPendingBroadcastTimeoutMessage = true;
11691 }
11692 }
11693
11694 private final void cancelBroadcastTimeoutLocked() {
11695 if (mPendingBroadcastTimeoutMessage) {
11696 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11697 mPendingBroadcastTimeoutMessage = false;
11698 }
11699 }
11700
11701 private final void broadcastTimeoutLocked(boolean fromMsg) {
11702 if (fromMsg) {
11703 mPendingBroadcastTimeoutMessage = false;
11704 }
11705
11706 if (mOrderedBroadcasts.size() == 0) {
11707 return;
11708 }
11709
11710 long now = SystemClock.uptimeMillis();
11711 BroadcastRecord r = mOrderedBroadcasts.get(0);
11712 if (fromMsg) {
11713 if (mDidDexOpt) {
11714 // Delay timeouts until dexopt finishes.
11715 mDidDexOpt = false;
11716 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11717 setBroadcastTimeoutLocked(timeoutTime);
11718 return;
11719 }
11720 if (! mProcessesReady) {
11721 // Only process broadcast timeouts if the system is ready. That way
11722 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11723 // to do heavy lifting for system up.
11724 return;
11725 }
11726
11727 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11728 if (timeoutTime > now) {
11729 // We can observe premature timeouts because we do not cancel and reset the
11730 // broadcast timeout message after each receiver finishes. Instead, we set up
11731 // an initial timeout then kick it down the road a little further as needed
11732 // when it expires.
11733 if (DEBUG_BROADCAST) Slog.v(TAG,
11734 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11735 + timeoutTime);
11736 setBroadcastTimeoutLocked(timeoutTime);
11737 return;
11738 }
11739 }
11740
11741 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11742 + ", started " + (now - r.receiverTime) + "ms ago");
11743 r.receiverTime = now;
11744 r.anrCount++;
11745
11746 // Current receiver has passed its expiration date.
11747 if (r.nextReceiver <= 0) {
11748 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11749 return;
11750 }
11751
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011752 ProcessRecord app = null;
11753 String anrMessage = null;
11754
Jeff Brown4d94a762010-09-23 11:33:28 -070011755 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11756 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11757 logBroadcastReceiverDiscardLocked(r);
11758 if (curReceiver instanceof BroadcastFilter) {
11759 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11760 if (bf.receiverList.pid != 0
11761 && bf.receiverList.pid != MY_PID) {
11762 synchronized (this.mPidsSelfLocked) {
11763 app = this.mPidsSelfLocked.get(
11764 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011766 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011767 } else {
11768 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011769 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011770
Jeff Brown4d94a762010-09-23 11:33:28 -070011771 if (app != null) {
11772 anrMessage = "Broadcast of " + r.intent.toString();
11773 }
11774
11775 if (mPendingBroadcast == r) {
11776 mPendingBroadcast = null;
11777 }
11778
11779 // Move on to the next receiver.
11780 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11781 r.resultExtras, r.resultAbort, true);
11782 scheduleBroadcastsLocked();
11783
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011784 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011785 // Post the ANR to the handler since we do not want to process ANRs while
11786 // potentially holding our lock.
11787 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011789 }
11790
11791 private final void processCurBroadcastLocked(BroadcastRecord r,
11792 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011793 if (DEBUG_BROADCAST) Slog.v(TAG,
11794 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011795 if (app.thread == null) {
11796 throw new RemoteException();
11797 }
11798 r.receiver = app.thread.asBinder();
11799 r.curApp = app;
11800 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011801 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011802
11803 // Tell the application to launch this receiver.
11804 r.intent.setComponent(r.curComponent);
11805
11806 boolean started = false;
11807 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011808 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011809 "Delivering to component " + r.curComponent
11810 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011811 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011812 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011813 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011814 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011815 if (DEBUG_BROADCAST) Slog.v(TAG,
11816 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011817 started = true;
11818 } finally {
11819 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011820 if (DEBUG_BROADCAST) Slog.v(TAG,
11821 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011822 r.receiver = null;
11823 r.curApp = null;
11824 app.curReceiver = null;
11825 }
11826 }
11827
11828 }
11829
Jeff Brown4d94a762010-09-23 11:33:28 -070011830 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011831 Intent intent, int resultCode, String data, Bundle extras,
11832 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011833 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011834 if (app != null && app.thread != null) {
11835 // If we have an app thread, do the call through that so it is
11836 // correctly ordered with other one-way calls.
11837 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011838 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011839 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011840 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841 }
11842 }
11843
Jeff Brown4d94a762010-09-23 11:33:28 -070011844 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011845 BroadcastFilter filter, boolean ordered) {
11846 boolean skip = false;
11847 if (filter.requiredPermission != null) {
11848 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011849 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011851 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011852 + r.intent.toString()
11853 + " from " + r.callerPackage + " (pid="
11854 + r.callingPid + ", uid=" + r.callingUid + ")"
11855 + " requires " + filter.requiredPermission
11856 + " due to registered receiver " + filter);
11857 skip = true;
11858 }
11859 }
11860 if (r.requiredPermission != null) {
11861 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011862 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011863 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011864 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011865 + r.intent.toString()
11866 + " to " + filter.receiverList.app
11867 + " (pid=" + filter.receiverList.pid
11868 + ", uid=" + filter.receiverList.uid + ")"
11869 + " requires " + r.requiredPermission
11870 + " due to sender " + r.callerPackage
11871 + " (uid " + r.callingUid + ")");
11872 skip = true;
11873 }
11874 }
11875
11876 if (!skip) {
11877 // If this is not being sent as an ordered broadcast, then we
11878 // don't want to touch the fields that keep track of the current
11879 // state of ordered broadcasts.
11880 if (ordered) {
11881 r.receiver = filter.receiverList.receiver.asBinder();
11882 r.curFilter = filter;
11883 filter.receiverList.curBroadcast = r;
11884 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011885 if (filter.receiverList.app != null) {
11886 // Bump hosting application to no longer be in background
11887 // scheduling class. Note that we can't do that if there
11888 // isn't an app... but we can only be in that case for
11889 // things that directly call the IActivityManager API, which
11890 // are already core system stuff so don't matter for this.
11891 r.curApp = filter.receiverList.app;
11892 filter.receiverList.app.curReceiver = r;
11893 updateOomAdjLocked();
11894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011895 }
11896 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011897 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011898 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011899 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011900 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011901 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011902 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011903 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011904 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011905 if (ordered) {
11906 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11907 }
11908 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011909 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011910 if (ordered) {
11911 r.receiver = null;
11912 r.curFilter = null;
11913 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011914 if (filter.receiverList.app != null) {
11915 filter.receiverList.app.curReceiver = null;
11916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011917 }
11918 }
11919 }
11920 }
11921
Dianne Hackborn12527f92009-11-11 17:39:50 -080011922 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11923 if (r.callingUid < 0) {
11924 // This was from a registerReceiver() call; ignore it.
11925 return;
11926 }
11927 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
11928 MAX_BROADCAST_HISTORY-1);
11929 r.finishTime = SystemClock.uptimeMillis();
11930 mBroadcastHistory[0] = r;
11931 }
11932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011933 private final void processNextBroadcast(boolean fromMsg) {
11934 synchronized(this) {
11935 BroadcastRecord r;
11936
Joe Onorato8a9b2202010-02-26 18:56:32 -080011937 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011938 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011939 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011940
11941 updateCpuStats();
11942
11943 if (fromMsg) {
11944 mBroadcastsScheduled = false;
11945 }
11946
11947 // First, deliver any non-serialized broadcasts right away.
11948 while (mParallelBroadcasts.size() > 0) {
11949 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080011950 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011951 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011952 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011953 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011954 for (int i=0; i<N; i++) {
11955 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011956 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011957 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011958 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070011959 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011960 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080011961 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011962 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011963 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011964 }
11965
11966 // Now take care of the next serialized one...
11967
11968 // If we are waiting for a process to come up to handle the next
11969 // broadcast, then do nothing at this point. Just in case, we
11970 // check that the process we're waiting for still exists.
11971 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011972 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011973 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070011974 + mPendingBroadcast.curApp);
11975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011976
11977 boolean isDead;
11978 synchronized (mPidsSelfLocked) {
11979 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
11980 }
11981 if (!isDead) {
11982 // It's still alive, so keep waiting
11983 return;
11984 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011985 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011986 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011987 mPendingBroadcast.state = BroadcastRecord.IDLE;
11988 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 mPendingBroadcast = null;
11990 }
11991 }
11992
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011993 boolean looped = false;
11994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011995 do {
11996 if (mOrderedBroadcasts.size() == 0) {
11997 // No more broadcasts pending, so all done!
11998 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011999 if (looped) {
12000 // If we had finished the last ordered broadcast, then
12001 // make sure all processes have correct oom and sched
12002 // adjustments.
12003 updateOomAdjLocked();
12004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012005 return;
12006 }
12007 r = mOrderedBroadcasts.get(0);
12008 boolean forceReceive = false;
12009
12010 // Ensure that even if something goes awry with the timeout
12011 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012012 // and continue to make progress.
12013 //
12014 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012015 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012016 // one time heavy lifting after system upgrades and can take
12017 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012018 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012019 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012020 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012021 if ((numReceivers > 0) &&
12022 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012023 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012024 + " now=" + now
12025 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012026 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012027 + " intent=" + r.intent
12028 + " numReceivers=" + numReceivers
12029 + " nextReceiver=" + r.nextReceiver
12030 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012031 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012032 forceReceive = true;
12033 r.state = BroadcastRecord.IDLE;
12034 }
12035 }
12036
12037 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012038 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012039 "processNextBroadcast() called when not idle (state="
12040 + r.state + ")");
12041 return;
12042 }
12043
12044 if (r.receivers == null || r.nextReceiver >= numReceivers
12045 || r.resultAbort || forceReceive) {
12046 // No more receivers for this broadcast! Send the final
12047 // result if requested...
12048 if (r.resultTo != null) {
12049 try {
12050 if (DEBUG_BROADCAST) {
12051 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012052 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012053 + " seq=" + seq + " app=" + r.callerApp);
12054 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012055 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012056 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012057 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012058 // Set this to null so that the reference
12059 // (local and remote) isnt kept in the mBroadcastHistory.
12060 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012062 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012063 }
12064 }
12065
Joe Onorato8a9b2202010-02-26 18:56:32 -080012066 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012067 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012068
Joe Onorato8a9b2202010-02-26 18:56:32 -080012069 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012070 + r);
12071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012072 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012073 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012074 mOrderedBroadcasts.remove(0);
12075 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012076 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012077 continue;
12078 }
12079 } while (r == null);
12080
12081 // Get the next receiver...
12082 int recIdx = r.nextReceiver++;
12083
12084 // Keep track of when this receiver started, and make sure there
12085 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012086 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012087 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012088 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012089
Joe Onorato8a9b2202010-02-26 18:56:32 -080012090 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012091 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012092 }
12093 if (! mPendingBroadcastTimeoutMessage) {
12094 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012095 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012096 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12097 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012098 }
12099
12100 Object nextReceiver = r.receivers.get(recIdx);
12101 if (nextReceiver instanceof BroadcastFilter) {
12102 // Simple case: this is a registered receiver who gets
12103 // a direct call.
12104 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012105 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012106 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012107 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012108 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012109 if (r.receiver == null || !r.ordered) {
12110 // The receiver has already finished, so schedule to
12111 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012112 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12113 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012114 r.state = BroadcastRecord.IDLE;
12115 scheduleBroadcastsLocked();
12116 }
12117 return;
12118 }
12119
12120 // Hard case: need to instantiate the receiver, possibly
12121 // starting its application process to host it.
12122
12123 ResolveInfo info =
12124 (ResolveInfo)nextReceiver;
12125
12126 boolean skip = false;
12127 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012128 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12129 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012130 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012131 if (!info.activityInfo.exported) {
12132 Slog.w(TAG, "Permission Denial: broadcasting "
12133 + r.intent.toString()
12134 + " from " + r.callerPackage + " (pid=" + r.callingPid
12135 + ", uid=" + r.callingUid + ")"
12136 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12137 + " due to receiver " + info.activityInfo.packageName
12138 + "/" + info.activityInfo.name);
12139 } else {
12140 Slog.w(TAG, "Permission Denial: broadcasting "
12141 + r.intent.toString()
12142 + " from " + r.callerPackage + " (pid=" + r.callingPid
12143 + ", uid=" + r.callingUid + ")"
12144 + " requires " + info.activityInfo.permission
12145 + " due to receiver " + info.activityInfo.packageName
12146 + "/" + info.activityInfo.name);
12147 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012148 skip = true;
12149 }
12150 if (r.callingUid != Process.SYSTEM_UID &&
12151 r.requiredPermission != null) {
12152 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012153 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012154 checkPermission(r.requiredPermission,
12155 info.activityInfo.applicationInfo.packageName);
12156 } catch (RemoteException e) {
12157 perm = PackageManager.PERMISSION_DENIED;
12158 }
12159 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012160 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012161 + r.intent + " to "
12162 + info.activityInfo.applicationInfo.packageName
12163 + " requires " + r.requiredPermission
12164 + " due to sender " + r.callerPackage
12165 + " (uid " + r.callingUid + ")");
12166 skip = true;
12167 }
12168 }
12169 if (r.curApp != null && r.curApp.crashing) {
12170 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012171 if (DEBUG_BROADCAST) Slog.v(TAG,
12172 "Skipping deliver ordered " + r + " to " + r.curApp
12173 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012174 skip = true;
12175 }
12176
12177 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012178 if (DEBUG_BROADCAST) Slog.v(TAG,
12179 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012180 r.receiver = null;
12181 r.curFilter = null;
12182 r.state = BroadcastRecord.IDLE;
12183 scheduleBroadcastsLocked();
12184 return;
12185 }
12186
12187 r.state = BroadcastRecord.APP_RECEIVE;
12188 String targetProcess = info.activityInfo.processName;
12189 r.curComponent = new ComponentName(
12190 info.activityInfo.applicationInfo.packageName,
12191 info.activityInfo.name);
12192 r.curReceiver = info.activityInfo;
12193
Dianne Hackborne7f97212011-02-24 14:40:20 -080012194 // Broadcast is being executed, its package can't be stopped.
12195 try {
12196 AppGlobals.getPackageManager().setPackageStoppedState(
12197 r.curComponent.getPackageName(), false);
12198 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012199 } catch (IllegalArgumentException e) {
12200 Slog.w(TAG, "Failed trying to unstop package "
12201 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012202 }
12203
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012204 // Is this receiver's application already running?
12205 ProcessRecord app = getProcessRecordLocked(targetProcess,
12206 info.activityInfo.applicationInfo.uid);
12207 if (app != null && app.thread != null) {
12208 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012209 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012210 processCurBroadcastLocked(r, app);
12211 return;
12212 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012213 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012214 + r.curComponent, e);
12215 }
12216
12217 // If a dead object exception was thrown -- fall through to
12218 // restart the application.
12219 }
12220
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012221 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012222 if (DEBUG_BROADCAST) Slog.v(TAG,
12223 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012224 if ((r.curApp=startProcessLocked(targetProcess,
12225 info.activityInfo.applicationInfo, true,
12226 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012227 "broadcast", r.curComponent,
12228 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12229 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012230 // Ah, this recipient is unavailable. Finish it if necessary,
12231 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012232 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012233 + info.activityInfo.applicationInfo.packageName + "/"
12234 + info.activityInfo.applicationInfo.uid + " for broadcast "
12235 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012236 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012237 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12238 r.resultExtras, r.resultAbort, true);
12239 scheduleBroadcastsLocked();
12240 r.state = BroadcastRecord.IDLE;
12241 return;
12242 }
12243
12244 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012245 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 }
12247 }
12248
12249 // =========================================================
12250 // INSTRUMENTATION
12251 // =========================================================
12252
12253 public boolean startInstrumentation(ComponentName className,
12254 String profileFile, int flags, Bundle arguments,
12255 IInstrumentationWatcher watcher) {
12256 // Refuse possible leaked file descriptors
12257 if (arguments != null && arguments.hasFileDescriptors()) {
12258 throw new IllegalArgumentException("File descriptors passed in Bundle");
12259 }
12260
12261 synchronized(this) {
12262 InstrumentationInfo ii = null;
12263 ApplicationInfo ai = null;
12264 try {
12265 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012266 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012267 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012268 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012269 } catch (PackageManager.NameNotFoundException e) {
12270 }
12271 if (ii == null) {
12272 reportStartInstrumentationFailure(watcher, className,
12273 "Unable to find instrumentation info for: " + className);
12274 return false;
12275 }
12276 if (ai == null) {
12277 reportStartInstrumentationFailure(watcher, className,
12278 "Unable to find instrumentation target package: " + ii.targetPackage);
12279 return false;
12280 }
12281
12282 int match = mContext.getPackageManager().checkSignatures(
12283 ii.targetPackage, ii.packageName);
12284 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12285 String msg = "Permission Denial: starting instrumentation "
12286 + className + " from pid="
12287 + Binder.getCallingPid()
12288 + ", uid=" + Binder.getCallingPid()
12289 + " not allowed because package " + ii.packageName
12290 + " does not have a signature matching the target "
12291 + ii.targetPackage;
12292 reportStartInstrumentationFailure(watcher, className, msg);
12293 throw new SecurityException(msg);
12294 }
12295
12296 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012297 forceStopPackageLocked(ii.targetPackage, -1, true, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012298 ProcessRecord app = addAppLocked(ai);
12299 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012300 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012301 app.instrumentationProfileFile = profileFile;
12302 app.instrumentationArguments = arguments;
12303 app.instrumentationWatcher = watcher;
12304 app.instrumentationResultClass = className;
12305 Binder.restoreCallingIdentity(origId);
12306 }
12307
12308 return true;
12309 }
12310
12311 /**
12312 * Report errors that occur while attempting to start Instrumentation. Always writes the
12313 * error to the logs, but if somebody is watching, send the report there too. This enables
12314 * the "am" command to report errors with more information.
12315 *
12316 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12317 * @param cn The component name of the instrumentation.
12318 * @param report The error report.
12319 */
12320 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12321 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012322 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012323 try {
12324 if (watcher != null) {
12325 Bundle results = new Bundle();
12326 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12327 results.putString("Error", report);
12328 watcher.instrumentationStatus(cn, -1, results);
12329 }
12330 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012331 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 }
12333 }
12334
12335 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12336 if (app.instrumentationWatcher != null) {
12337 try {
12338 // NOTE: IInstrumentationWatcher *must* be oneway here
12339 app.instrumentationWatcher.instrumentationFinished(
12340 app.instrumentationClass,
12341 resultCode,
12342 results);
12343 } catch (RemoteException e) {
12344 }
12345 }
12346 app.instrumentationWatcher = null;
12347 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012348 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349 app.instrumentationProfileFile = null;
12350 app.instrumentationArguments = null;
12351
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080012352 forceStopPackageLocked(app.processName, -1, false, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012353 }
12354
12355 public void finishInstrumentation(IApplicationThread target,
12356 int resultCode, Bundle results) {
12357 // Refuse possible leaked file descriptors
12358 if (results != null && results.hasFileDescriptors()) {
12359 throw new IllegalArgumentException("File descriptors passed in Intent");
12360 }
12361
12362 synchronized(this) {
12363 ProcessRecord app = getRecordForAppLocked(target);
12364 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012365 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012366 return;
12367 }
12368 final long origId = Binder.clearCallingIdentity();
12369 finishInstrumentationLocked(app, resultCode, results);
12370 Binder.restoreCallingIdentity(origId);
12371 }
12372 }
12373
12374 // =========================================================
12375 // CONFIGURATION
12376 // =========================================================
12377
12378 public ConfigurationInfo getDeviceConfigurationInfo() {
12379 ConfigurationInfo config = new ConfigurationInfo();
12380 synchronized (this) {
12381 config.reqTouchScreen = mConfiguration.touchscreen;
12382 config.reqKeyboardType = mConfiguration.keyboard;
12383 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012384 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12385 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012386 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12387 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012388 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12389 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012390 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12391 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012392 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012393 }
12394 return config;
12395 }
12396
12397 public Configuration getConfiguration() {
12398 Configuration ci;
12399 synchronized(this) {
12400 ci = new Configuration(mConfiguration);
12401 }
12402 return ci;
12403 }
12404
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012405 public void updatePersistentConfiguration(Configuration values) {
12406 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12407 "updateConfiguration()");
12408 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12409 "updateConfiguration()");
12410 if (values == null) {
12411 throw new NullPointerException("Configuration must not be null");
12412 }
12413
12414 synchronized(this) {
12415 final long origId = Binder.clearCallingIdentity();
12416 updateConfigurationLocked(values, null, true);
12417 Binder.restoreCallingIdentity(origId);
12418 }
12419 }
12420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012421 public void updateConfiguration(Configuration values) {
12422 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12423 "updateConfiguration()");
12424
12425 synchronized(this) {
12426 if (values == null && mWindowManager != null) {
12427 // sentinel: fetch the current configuration from the window manager
12428 values = mWindowManager.computeNewConfiguration();
12429 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012430
12431 if (mWindowManager != null) {
12432 mProcessList.applyDisplaySize(mWindowManager);
12433 }
12434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012435 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012436 if (values != null) {
12437 Settings.System.clearConfiguration(values);
12438 }
12439 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012440 Binder.restoreCallingIdentity(origId);
12441 }
12442 }
12443
12444 /**
12445 * Do either or both things: (1) change the current configuration, and (2)
12446 * make sure the given activity is running with the (now) current
12447 * configuration. Returns true if the activity has been left running, or
12448 * false if <var>starting</var> is being destroyed to match the new
12449 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012450 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012451 */
12452 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012453 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012454 int changes = 0;
12455
12456 boolean kept = true;
12457
12458 if (values != null) {
12459 Configuration newConfig = new Configuration(mConfiguration);
12460 changes = newConfig.updateFrom(values);
12461 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012462 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012463 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012464 }
12465
Doug Zongker2bec3d42009-12-04 12:52:44 -080012466 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012467
12468 if (values.locale != null) {
12469 saveLocaleLocked(values.locale,
12470 !values.locale.equals(mConfiguration.locale),
12471 values.userSetLocale);
12472 }
12473
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012474 mConfigurationSeq++;
12475 if (mConfigurationSeq <= 0) {
12476 mConfigurationSeq = 1;
12477 }
12478 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012479 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012480 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012481
12482 AttributeCache ac = AttributeCache.instance();
12483 if (ac != null) {
12484 ac.updateConfiguration(mConfiguration);
12485 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012486
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012487 // Make sure all resources in our process are updated
12488 // right now, so that anyone who is going to retrieve
12489 // resource values after we return will be sure to get
12490 // the new ones. This is especially important during
12491 // boot, where the first config change needs to guarantee
12492 // all resources have that config before following boot
12493 // code is executed.
12494 mSystemThread.applyConfigurationToResources(newConfig);
12495
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012496 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012497 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12498 msg.obj = new Configuration(mConfiguration);
12499 mHandler.sendMessage(msg);
12500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012501
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012502 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12503 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 try {
12505 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012506 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012507 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012508 app.thread.scheduleConfigurationChanged(mConfiguration);
12509 }
12510 } catch (Exception e) {
12511 }
12512 }
12513 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012514 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12515 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012516 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12517 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012518 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12519 broadcastIntentLocked(null, null,
12520 new Intent(Intent.ACTION_LOCALE_CHANGED),
12521 null, null, 0, null, null,
12522 null, false, false, MY_PID, Process.SYSTEM_UID);
12523 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012524 }
12525 }
12526
12527 if (changes != 0 && starting == null) {
12528 // If the configuration changed, and the caller is not already
12529 // in the process of starting an activity, then find the top
12530 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012531 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012532 }
12533
12534 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012535 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012536 // And we need to make sure at this point that all other activities
12537 // are made visible with the correct configuration.
12538 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012539 }
12540
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012541 if (values != null && mWindowManager != null) {
12542 mWindowManager.setNewConfiguration(mConfiguration);
12543 }
12544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012545 return kept;
12546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012547
12548 /**
12549 * Save the locale. You must be inside a synchronized (this) block.
12550 */
12551 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12552 if(isDiff) {
12553 SystemProperties.set("user.language", l.getLanguage());
12554 SystemProperties.set("user.region", l.getCountry());
12555 }
12556
12557 if(isPersist) {
12558 SystemProperties.set("persist.sys.language", l.getLanguage());
12559 SystemProperties.set("persist.sys.country", l.getCountry());
12560 SystemProperties.set("persist.sys.localevar", l.getVariant());
12561 }
12562 }
12563
12564 // =========================================================
12565 // LIFETIME MANAGEMENT
12566 // =========================================================
12567
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012568 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12569 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012570 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012571 // This adjustment has already been computed. If we are calling
12572 // from the top, we may have already computed our adjustment with
12573 // an earlier hidden adjustment that isn't really for us... if
12574 // so, use the new hidden adjustment.
12575 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012576 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012577 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012578 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012579 }
12580
12581 if (app.thread == null) {
12582 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012583 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012584 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012585 }
12586
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012587 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12588 app.adjSource = null;
12589 app.adjTarget = null;
12590 app.empty = false;
12591 app.hidden = false;
12592
12593 final int activitiesSize = app.activities.size();
12594
Dianne Hackborn7d608422011-08-07 16:24:18 -070012595 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012596 // The max adjustment doesn't allow this app to be anything
12597 // below foreground, so it is not worth doing work for it.
12598 app.adjType = "fixed";
12599 app.adjSeq = mAdjSeq;
12600 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012601 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012602 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012603 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012604 // System process can do UI, and when they do we want to have
12605 // them trim their memory after the user leaves the UI. To
12606 // facilitate this, here we need to determine whether or not it
12607 // is currently showing UI.
12608 app.systemNoUi = true;
12609 if (app == TOP_APP) {
12610 app.systemNoUi = false;
12611 } else if (activitiesSize > 0) {
12612 for (int j = 0; j < activitiesSize; j++) {
12613 final ActivityRecord r = app.activities.get(j);
12614 if (r.visible) {
12615 app.systemNoUi = false;
12616 break;
12617 }
12618 }
12619 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012620 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012621 }
12622
12623 final boolean hadForegroundActivities = app.foregroundActivities;
12624
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012625 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012626 app.keeping = false;
12627 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012628
The Android Open Source Project4df24232009-03-05 14:34:35 -080012629 // Determine the importance of the process, starting with most
12630 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012631 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012632 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012633 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012634 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012635 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012636 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012637 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012638 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012639 } else if (app.instrumentationClass != null) {
12640 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012641 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012642 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012643 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012644 } else if (app.curReceiver != null ||
12645 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12646 // An app that is currently receiving a broadcast also
12647 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012648 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012649 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012650 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012651 } else if (app.executingServices.size() > 0) {
12652 // An app that is currently executing a service callback also
12653 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012654 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012655 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012656 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012657 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012658 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012659 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012660 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012661 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012662 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012663 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012664 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012665 // A very not-needed process. If this is lower in the lru list,
12666 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012667 adj = hiddenAdj;
12668 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012669 app.hidden = true;
12670 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012671 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012672 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012673
12674 // Examine all activities if not already foreground.
12675 if (!app.foregroundActivities && activitiesSize > 0) {
12676 for (int j = 0; j < activitiesSize; j++) {
12677 final ActivityRecord r = app.activities.get(j);
12678 if (r.visible) {
12679 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012680 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12681 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012682 app.adjType = "visible";
12683 }
12684 schedGroup = Process.THREAD_GROUP_DEFAULT;
12685 app.hidden = false;
12686 app.foregroundActivities = true;
12687 break;
12688 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12689 || r.state == ActivityState.STOPPING) {
12690 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012691 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12692 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012693 app.adjType = "stopping";
12694 }
12695 app.foregroundActivities = true;
12696 }
12697 }
12698 }
12699
Dianne Hackborn7d608422011-08-07 16:24:18 -070012700 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012701 if (app.foregroundServices) {
12702 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012703 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012704 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012705 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012706 } else if (app.forcingToForeground != null) {
12707 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012708 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012709 app.adjType = "force-foreground";
12710 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012711 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012712 }
12713 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012714
Dianne Hackborn7d608422011-08-07 16:24:18 -070012715 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012716 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012717 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012718 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12719 app.adjType = "heavy";
12720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012721
Dianne Hackborn7d608422011-08-07 16:24:18 -070012722 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012723 // This process is hosting what we currently consider to be the
12724 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012725 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012726 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12727 app.adjType = "home";
12728 }
12729
Joe Onorato8a9b2202010-02-26 18:56:32 -080012730 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012731
The Android Open Source Project4df24232009-03-05 14:34:35 -080012732 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012733 // there are applications dependent on our services or providers, but
12734 // this gives us a baseline and makes sure we don't get into an
12735 // infinite recursion.
12736 app.adjSeq = mAdjSeq;
12737 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012738
Christopher Tate6fa95972009-06-05 18:43:55 -070012739 if (mBackupTarget != null && app == mBackupTarget.app) {
12740 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012741 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012742 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012743 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012744 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012745 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012746 }
12747 }
12748
Dianne Hackborn7d608422011-08-07 16:24:18 -070012749 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012750 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012751 final long now = SystemClock.uptimeMillis();
12752 // This process is more important if the top activity is
12753 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012754 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012755 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012756 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012757 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012758 if (app.hasShownUi) {
12759 // If this process has shown some UI, let it immediately
12760 // go to the LRU list because it may be pretty heavy with
12761 // UI stuff. We'll tag it with a label just to help
12762 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012763 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012764 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012765 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012766 } else {
12767 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12768 // This service has seen some activity within
12769 // recent memory, so we will keep its process ahead
12770 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012771 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
12772 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012773 app.adjType = "started-services";
12774 app.hidden = false;
12775 }
12776 }
12777 // If we have let the service slide into the background
12778 // state, still have some text describing what it is doing
12779 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012780 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012781 app.adjType = "started-bg-services";
12782 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012783 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012784 // Don't kill this process because it is doing work; it
12785 // has said it is doing work.
12786 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012787 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012788 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012789 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012790 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012791 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012792 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012793 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012794 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012795 // XXX should compute this based on the max of
12796 // all connected clients.
12797 ConnectionRecord cr = clist.get(i);
12798 if (cr.binding.client == app) {
12799 // Binding to ourself is not interesting.
12800 continue;
12801 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012802 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012803 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012804 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012805 int myHiddenAdj = hiddenAdj;
12806 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012807 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012808 myHiddenAdj = client.hiddenAdj;
12809 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012810 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012811 }
12812 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012813 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012814 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012815 String adjType = null;
12816 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12817 // Not doing bind OOM management, so treat
12818 // this guy more like a started service.
12819 if (app.hasShownUi) {
12820 // If this process has shown some UI, let it immediately
12821 // go to the LRU list because it may be pretty heavy with
12822 // UI stuff. We'll tag it with a label just to help
12823 // debug and understand what is going on.
12824 if (adj > clientAdj) {
12825 adjType = "bound-bg-ui-services";
12826 }
12827 clientAdj = adj;
12828 } else {
12829 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12830 // This service has not seen activity within
12831 // recent memory, so allow it to drop to the
12832 // LRU list if there is no other reason to keep
12833 // it around. We'll also tag it with a label just
12834 // to help debug and undertand what is going on.
12835 if (adj > clientAdj) {
12836 adjType = "bound-bg-services";
12837 }
12838 clientAdj = adj;
12839 }
12840 }
12841 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012842 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012843 // If this process has recently shown UI, and
12844 // the process that is binding to it is less
12845 // important than being visible, then we don't
12846 // care about the binding as much as we care
12847 // about letting this process get into the LRU
12848 // list to be killed and restarted if needed for
12849 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012850 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012851 adjType = "bound-bg-ui-services";
12852 } else {
12853 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12854 |Context.BIND_IMPORTANT)) != 0) {
12855 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012856 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012857 adj = clientAdj;
12858 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012859 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012860 }
12861 if (!client.hidden) {
12862 app.hidden = false;
12863 }
12864 if (client.keeping) {
12865 app.keeping = true;
12866 }
12867 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012868 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012869 }
12870 if (adjType != null) {
12871 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012872 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12873 .REASON_SERVICE_IN_USE;
12874 app.adjSource = cr.binding.client;
12875 app.adjTarget = s.name;
12876 }
12877 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12878 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12879 schedGroup = Process.THREAD_GROUP_DEFAULT;
12880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012881 }
12882 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012883 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12884 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012885 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012886 (a.visible || a.state == ActivityState.RESUMED
12887 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012888 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012889 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12890 schedGroup = Process.THREAD_GROUP_DEFAULT;
12891 }
12892 app.hidden = false;
12893 app.adjType = "service";
12894 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12895 .REASON_SERVICE_IN_USE;
12896 app.adjSource = a;
12897 app.adjTarget = s.name;
12898 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012900 }
12901 }
12902 }
12903 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012904
Dianne Hackborn287952c2010-09-22 22:34:31 -070012905 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012906 // would like to avoid killing it unless it would prevent the current
12907 // application from running. By default we put the process in
12908 // with the rest of the background processes; as we scan through
12909 // its services we may bump it up from there.
12910 if (adj > hiddenAdj) {
12911 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012912 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012913 app.adjType = "bg-services";
12914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012915 }
12916
Dianne Hackborn7d608422011-08-07 16:24:18 -070012917 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012918 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012919 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012920 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012921 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012922 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012923 if (cpr.clients.size() != 0) {
12924 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012925 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012926 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070012927 if (client == app) {
12928 // Being our own client is not interesting.
12929 continue;
12930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012931 int myHiddenAdj = hiddenAdj;
12932 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012933 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012934 myHiddenAdj = client.hiddenAdj;
12935 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012936 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012937 }
12938 }
12939 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012940 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012942 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012943 app.adjType = "bg-ui-provider";
12944 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012945 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12946 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012947 app.adjType = "provider";
12948 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012949 if (!client.hidden) {
12950 app.hidden = false;
12951 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012952 if (client.keeping) {
12953 app.keeping = true;
12954 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012955 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12956 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012957 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012958 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012959 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012960 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12961 schedGroup = Process.THREAD_GROUP_DEFAULT;
12962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963 }
12964 }
12965 // If the provider has external (non-framework) process
12966 // dependencies, ensure that its adjustment is at least
12967 // FOREGROUND_APP_ADJ.
12968 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012969 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12970 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012971 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012972 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012973 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012974 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012975 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012976 }
12977 }
12978 }
12979 }
12980
12981 app.curRawAdj = adj;
12982
Joe Onorato8a9b2202010-02-26 18:56:32 -080012983 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012984 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12985 if (adj > app.maxAdj) {
12986 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012987 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012988 schedGroup = Process.THREAD_GROUP_DEFAULT;
12989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012990 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012991 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012992 app.keeping = true;
12993 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012994
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012995 if (app.hasAboveClient) {
12996 // If this process has bound to any services with BIND_ABOVE_CLIENT,
12997 // then we need to drop its adjustment to be lower than the service's
12998 // in order to honor the request. We want to drop it by one adjustment
12999 // level... but there is special meaning applied to various levels so
13000 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013001 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013002 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013003 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13004 adj = ProcessList.VISIBLE_APP_ADJ;
13005 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13006 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13007 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13008 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13009 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013010 adj++;
13011 }
13012 }
13013
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013014 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013015 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013016
13017 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013018 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13019 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013020 }
13021
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013022 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013023 }
13024
13025 /**
13026 * Ask a given process to GC right now.
13027 */
13028 final void performAppGcLocked(ProcessRecord app) {
13029 try {
13030 app.lastRequestedGc = SystemClock.uptimeMillis();
13031 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013032 if (app.reportLowMemory) {
13033 app.reportLowMemory = false;
13034 app.thread.scheduleLowMemory();
13035 } else {
13036 app.thread.processInBackground();
13037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013038 }
13039 } catch (Exception e) {
13040 // whatever.
13041 }
13042 }
13043
13044 /**
13045 * Returns true if things are idle enough to perform GCs.
13046 */
Josh Bartel7f208742010-02-25 11:01:44 -060013047 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013048 return mParallelBroadcasts.size() == 0
13049 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013050 && (mSleeping || (mMainStack.mResumedActivity != null &&
13051 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013052 }
13053
13054 /**
13055 * Perform GCs on all processes that are waiting for it, but only
13056 * if things are idle.
13057 */
13058 final void performAppGcsLocked() {
13059 final int N = mProcessesToGc.size();
13060 if (N <= 0) {
13061 return;
13062 }
Josh Bartel7f208742010-02-25 11:01:44 -060013063 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013064 while (mProcessesToGc.size() > 0) {
13065 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013066 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013067 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13068 <= SystemClock.uptimeMillis()) {
13069 // To avoid spamming the system, we will GC processes one
13070 // at a time, waiting a few seconds between each.
13071 performAppGcLocked(proc);
13072 scheduleAppGcsLocked();
13073 return;
13074 } else {
13075 // It hasn't been long enough since we last GCed this
13076 // process... put it in the list to wait for its time.
13077 addProcessToGcListLocked(proc);
13078 break;
13079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013080 }
13081 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013082
13083 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013084 }
13085 }
13086
13087 /**
13088 * If all looks good, perform GCs on all processes waiting for them.
13089 */
13090 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013091 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013092 performAppGcsLocked();
13093 return;
13094 }
13095 // Still not idle, wait some more.
13096 scheduleAppGcsLocked();
13097 }
13098
13099 /**
13100 * Schedule the execution of all pending app GCs.
13101 */
13102 final void scheduleAppGcsLocked() {
13103 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013104
13105 if (mProcessesToGc.size() > 0) {
13106 // Schedule a GC for the time to the next process.
13107 ProcessRecord proc = mProcessesToGc.get(0);
13108 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13109
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013110 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013111 long now = SystemClock.uptimeMillis();
13112 if (when < (now+GC_TIMEOUT)) {
13113 when = now + GC_TIMEOUT;
13114 }
13115 mHandler.sendMessageAtTime(msg, when);
13116 }
13117 }
13118
13119 /**
13120 * Add a process to the array of processes waiting to be GCed. Keeps the
13121 * list in sorted order by the last GC time. The process can't already be
13122 * on the list.
13123 */
13124 final void addProcessToGcListLocked(ProcessRecord proc) {
13125 boolean added = false;
13126 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13127 if (mProcessesToGc.get(i).lastRequestedGc <
13128 proc.lastRequestedGc) {
13129 added = true;
13130 mProcessesToGc.add(i+1, proc);
13131 break;
13132 }
13133 }
13134 if (!added) {
13135 mProcessesToGc.add(0, proc);
13136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013137 }
13138
13139 /**
13140 * Set up to ask a process to GC itself. This will either do it
13141 * immediately, or put it on the list of processes to gc the next
13142 * time things are idle.
13143 */
13144 final void scheduleAppGcLocked(ProcessRecord app) {
13145 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013146 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013147 return;
13148 }
13149 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013150 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013151 scheduleAppGcsLocked();
13152 }
13153 }
13154
Dianne Hackborn287952c2010-09-22 22:34:31 -070013155 final void checkExcessivePowerUsageLocked(boolean doKills) {
13156 updateCpuStatsNow();
13157
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013158 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013159 boolean doWakeKills = doKills;
13160 boolean doCpuKills = doKills;
13161 if (mLastPowerCheckRealtime == 0) {
13162 doWakeKills = false;
13163 }
13164 if (mLastPowerCheckUptime == 0) {
13165 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013166 }
13167 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013168 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013169 }
13170 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013171 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13172 final long curUptime = SystemClock.uptimeMillis();
13173 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13174 mLastPowerCheckRealtime = curRealtime;
13175 mLastPowerCheckUptime = curUptime;
13176 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13177 doWakeKills = false;
13178 }
13179 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13180 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013181 }
13182 int i = mLruProcesses.size();
13183 while (i > 0) {
13184 i--;
13185 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013186 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013187 long wtime;
13188 synchronized (stats) {
13189 wtime = stats.getProcessWakeTime(app.info.uid,
13190 app.pid, curRealtime);
13191 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013192 long wtimeUsed = wtime - app.lastWakeTime;
13193 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13194 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013195 StringBuilder sb = new StringBuilder(128);
13196 sb.append("Wake for ");
13197 app.toShortString(sb);
13198 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013199 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013200 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013201 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013202 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013203 sb.append((wtimeUsed*100)/realtimeSince);
13204 sb.append("%)");
13205 Slog.i(TAG, sb.toString());
13206 sb.setLength(0);
13207 sb.append("CPU for ");
13208 app.toShortString(sb);
13209 sb.append(": over ");
13210 TimeUtils.formatDuration(uptimeSince, sb);
13211 sb.append(" used ");
13212 TimeUtils.formatDuration(cputimeUsed, sb);
13213 sb.append(" (");
13214 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013215 sb.append("%)");
13216 Slog.i(TAG, sb.toString());
13217 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013218 // If a process has held a wake lock for more
13219 // than 50% of the time during this period,
13220 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013221 if (doWakeKills && realtimeSince > 0
13222 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13223 synchronized (stats) {
13224 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13225 realtimeSince, wtimeUsed);
13226 }
13227 Slog.w(TAG, "Excessive wake lock in " + app.processName
13228 + " (pid " + app.pid + "): held " + wtimeUsed
13229 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013230 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13231 app.processName, app.setAdj, "excessive wake lock");
13232 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013233 } else if (doCpuKills && uptimeSince > 0
13234 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13235 synchronized (stats) {
13236 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13237 uptimeSince, cputimeUsed);
13238 }
13239 Slog.w(TAG, "Excessive CPU in " + app.processName
13240 + " (pid " + app.pid + "): used " + cputimeUsed
13241 + " during " + uptimeSince);
13242 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13243 app.processName, app.setAdj, "excessive cpu");
13244 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013245 } else {
13246 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013247 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013248 }
13249 }
13250 }
13251 }
13252
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013253 private final void updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013254 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 app.hiddenAdj = hiddenAdj;
13256
13257 if (app.thread == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013258 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013259 }
13260
Dianne Hackborn287952c2010-09-22 22:34:31 -070013261 final boolean wasKeeping = app.keeping;
13262
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013263 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013264
Jeff Brown10e89712011-07-08 18:52:57 -070013265 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013266 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13267 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013268 // If this app is transitioning from foreground to
13269 // non-foreground, have it do a gc.
13270 scheduleAppGcLocked(app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013271 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13272 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013273 // Likewise do a gc when an app is moving in to the
13274 // background (such as a service stopping).
13275 scheduleAppGcLocked(app);
13276 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013277
Jeff Brown10e89712011-07-08 18:52:57 -070013278 if (wasKeeping && !app.keeping) {
13279 // This app is no longer something we want to keep. Note
13280 // its current wake lock time to later know to kill it if
13281 // it is not behaving well.
13282 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13283 synchronized (stats) {
13284 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13285 app.pid, SystemClock.elapsedRealtime());
13286 }
13287 app.lastCpuTime = app.curCpuTime;
13288 }
13289
13290 app.setRawAdj = app.curRawAdj;
13291 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013292 if (app.curAdj != app.setAdj) {
13293 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013294 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13295 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013296 " oom adj to " + app.curAdj + " because " + app.adjType);
13297 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013298 } else {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013299 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013300 }
13301 }
13302 if (app.setSchedGroup != app.curSchedGroup) {
13303 app.setSchedGroup = app.curSchedGroup;
13304 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13305 "Setting process group of " + app.processName
13306 + " to " + app.curSchedGroup);
13307 if (app.waitingToKill != null &&
13308 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13309 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13310 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13311 app.processName, app.setAdj, app.waitingToKill);
13312 Process.killProcessQuiet(app.pid);
13313 } else {
13314 if (true) {
13315 long oldId = Binder.clearCallingIdentity();
13316 try {
13317 Process.setProcessGroup(app.pid, app.curSchedGroup);
13318 } catch (Exception e) {
13319 Slog.w(TAG, "Failed setting process group of " + app.pid
13320 + " to " + app.curSchedGroup);
13321 e.printStackTrace();
13322 } finally {
13323 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013324 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013325 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013326 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013327 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013328 app.thread.setSchedulingGroup(app.curSchedGroup);
13329 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013330 }
13331 }
13332 }
13333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013334 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013335 }
13336
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013337 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013338 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013339 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013340 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013341 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013342 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013343 }
13344 }
13345 return resumedActivity;
13346 }
13347
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013348 private final void updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013349 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013350 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13351 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013352 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13353 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013354
13355 mAdjSeq++;
13356
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013357 updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013358 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13359 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013360 if (nowHidden != wasHidden) {
13361 // Changed to/from hidden state, so apps after it in the LRU
13362 // list may also be changed.
13363 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013364 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013365 }
13366
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013367 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013368 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013369 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13370
13371 if (false) {
13372 RuntimeException e = new RuntimeException();
13373 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013374 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013375 }
13376
13377 mAdjSeq++;
13378
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013379 // Let's determine how many processes we have running vs.
13380 // how many slots we have for background processes; we may want
13381 // to put multiple processes in a slot of there are enough of
13382 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013383 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013384 int factor = (mLruProcesses.size()-4)/numSlots;
13385 if (factor < 1) factor = 1;
13386 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013387 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013388
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013389 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013390 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013391 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013392 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013393 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013394 while (i > 0) {
13395 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013396 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013397 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013398 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013399 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013400 && app.curAdj == curHiddenAdj) {
13401 step++;
13402 if (step >= factor) {
13403 step = 0;
13404 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013405 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013406 }
13407 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013408 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013409 numHidden++;
13410 if (numHidden > mProcessLimit) {
13411 Slog.i(TAG, "No longer want " + app.processName
13412 + " (pid " + app.pid + "): hidden #" + numHidden);
13413 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13414 app.processName, app.setAdj, "too many background");
13415 app.killedBackground = true;
13416 Process.killProcessQuiet(app.pid);
13417 } else {
13418 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013419 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013420 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013421 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013423 }
13424 }
13425
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013426 // Now determine the memory trimming level of background processes.
13427 // Unfortunately we need to start at the back of the list to do this
13428 // properly. We only do this if the number of background apps we
13429 // are managing to keep around is less than half the maximum we desire;
13430 // if we are keeping a good number around, we'll let them use whatever
13431 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013432 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013433 final int N = mLruProcesses.size();
13434 factor = numBg/3;
13435 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013436 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013437 for (i=0; i<N; i++) {
13438 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013439 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013440 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13441 try {
13442 app.thread.scheduleTrimMemory(curLevel);
13443 } catch (RemoteException e) {
13444 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013445 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013446 // For these apps we will also finish their activities
13447 // to help them free memory.
13448 mMainStack.destroyActivitiesLocked(app, false);
13449 }
13450 }
13451 app.trimMemoryLevel = curLevel;
13452 step++;
13453 if (step >= factor) {
13454 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013455 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13456 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013457 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013458 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13459 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013460 break;
13461 }
13462 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013463 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013464 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013465 && app.thread != null) {
13466 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013467 app.thread.scheduleTrimMemory(
13468 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013469 } catch (RemoteException e) {
13470 }
13471 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013472 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013473 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013474 && app.pendingUiClean) {
13475 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13476 && app.thread != null) {
13477 try {
13478 app.thread.scheduleTrimMemory(
13479 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13480 } catch (RemoteException e) {
13481 }
13482 }
13483 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13484 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013485 } else {
13486 app.trimMemoryLevel = 0;
13487 }
13488 }
13489 } else {
13490 final int N = mLruProcesses.size();
13491 for (i=0; i<N; i++) {
13492 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013493 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013494 && app.pendingUiClean) {
13495 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13496 && app.thread != null) {
13497 try {
13498 app.thread.scheduleTrimMemory(
13499 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13500 } catch (RemoteException e) {
13501 }
13502 }
13503 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13504 app.pendingUiClean = false;
13505 } else {
13506 app.trimMemoryLevel = 0;
13507 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013508 }
13509 }
13510
13511 if (mAlwaysFinishActivities) {
13512 mMainStack.destroyActivitiesLocked(null, false);
13513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013514 }
13515
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013516 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517 synchronized (this) {
13518 int i;
13519
13520 // First remove any unused application processes whose package
13521 // has been removed.
13522 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13523 final ProcessRecord app = mRemovedProcesses.get(i);
13524 if (app.activities.size() == 0
13525 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013526 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013527 TAG, "Exiting empty application process "
13528 + app.processName + " ("
13529 + (app.thread != null ? app.thread.asBinder() : null)
13530 + ")\n");
13531 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013532 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13533 app.processName, app.setAdj, "empty");
13534 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013535 } else {
13536 try {
13537 app.thread.scheduleExit();
13538 } catch (Exception e) {
13539 // Ignore exceptions.
13540 }
13541 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013542 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013543 mRemovedProcesses.remove(i);
13544
13545 if (app.persistent) {
13546 if (app.persistent) {
13547 addAppLocked(app.info);
13548 }
13549 }
13550 }
13551 }
13552
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013553 // Now update the oom adj for all processes.
13554 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013555 }
13556 }
13557
13558 /** This method sends the specified signal to each of the persistent apps */
13559 public void signalPersistentProcesses(int sig) throws RemoteException {
13560 if (sig != Process.SIGNAL_USR1) {
13561 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13562 }
13563
13564 synchronized (this) {
13565 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13566 != PackageManager.PERMISSION_GRANTED) {
13567 throw new SecurityException("Requires permission "
13568 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13569 }
13570
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013571 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13572 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013573 if (r.thread != null && r.persistent) {
13574 Process.sendSignal(r.pid, sig);
13575 }
13576 }
13577 }
13578 }
13579
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013580 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013581 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013582
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013583 try {
13584 synchronized (this) {
13585 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13586 // its own permission.
13587 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13588 != PackageManager.PERMISSION_GRANTED) {
13589 throw new SecurityException("Requires permission "
13590 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013591 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013592
13593 if (start && fd == null) {
13594 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013595 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013596
13597 ProcessRecord proc = null;
13598 try {
13599 int pid = Integer.parseInt(process);
13600 synchronized (mPidsSelfLocked) {
13601 proc = mPidsSelfLocked.get(pid);
13602 }
13603 } catch (NumberFormatException e) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013604 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013605
13606 if (proc == null) {
13607 HashMap<String, SparseArray<ProcessRecord>> all
13608 = mProcessNames.getMap();
13609 SparseArray<ProcessRecord> procs = all.get(process);
13610 if (procs != null && procs.size() > 0) {
13611 proc = procs.valueAt(0);
13612 }
13613 }
13614
13615 if (proc == null || proc.thread == null) {
13616 throw new IllegalArgumentException("Unknown process: " + process);
13617 }
13618
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013619 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13620 if (!isDebuggable) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013621 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13622 throw new SecurityException("Process not debuggable: " + proc);
13623 }
13624 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013625
Romain Guy7eabe552011-07-21 14:56:34 -070013626 proc.thread.profilerControl(start, path, fd, profileType);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013627 fd = null;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013628 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013629 }
13630 } catch (RemoteException e) {
13631 throw new IllegalStateException("Process disappeared");
13632 } finally {
13633 if (fd != null) {
13634 try {
13635 fd.close();
13636 } catch (IOException e) {
13637 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013638 }
13639 }
13640 }
Andy McFadden824c5102010-07-09 16:26:57 -070013641
13642 public boolean dumpHeap(String process, boolean managed,
13643 String path, ParcelFileDescriptor fd) throws RemoteException {
13644
13645 try {
13646 synchronized (this) {
13647 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13648 // its own permission (same as profileControl).
13649 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13650 != PackageManager.PERMISSION_GRANTED) {
13651 throw new SecurityException("Requires permission "
13652 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13653 }
13654
13655 if (fd == null) {
13656 throw new IllegalArgumentException("null fd");
13657 }
13658
13659 ProcessRecord proc = null;
13660 try {
13661 int pid = Integer.parseInt(process);
13662 synchronized (mPidsSelfLocked) {
13663 proc = mPidsSelfLocked.get(pid);
13664 }
13665 } catch (NumberFormatException e) {
13666 }
13667
13668 if (proc == null) {
13669 HashMap<String, SparseArray<ProcessRecord>> all
13670 = mProcessNames.getMap();
13671 SparseArray<ProcessRecord> procs = all.get(process);
13672 if (procs != null && procs.size() > 0) {
13673 proc = procs.valueAt(0);
13674 }
13675 }
13676
13677 if (proc == null || proc.thread == null) {
13678 throw new IllegalArgumentException("Unknown process: " + process);
13679 }
13680
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013681 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13682 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013683 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13684 throw new SecurityException("Process not debuggable: " + proc);
13685 }
13686 }
13687
13688 proc.thread.dumpHeap(managed, path, fd);
13689 fd = null;
13690 return true;
13691 }
13692 } catch (RemoteException e) {
13693 throw new IllegalStateException("Process disappeared");
13694 } finally {
13695 if (fd != null) {
13696 try {
13697 fd.close();
13698 } catch (IOException e) {
13699 }
13700 }
13701 }
13702 }
13703
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013704 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13705 public void monitor() {
13706 synchronized (this) { }
13707 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013708
13709 public void onCoreSettingsChange(Bundle settings) {
13710 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13711 ProcessRecord processRecord = mLruProcesses.get(i);
13712 try {
13713 if (processRecord.thread != null) {
13714 processRecord.thread.setCoreSettings(settings);
13715 }
13716 } catch (RemoteException re) {
13717 /* ignore */
13718 }
13719 }
13720 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013721
13722 // Multi-user methods
13723
13724 public boolean switchUser(int userid) {
13725 // TODO
13726 return true;
13727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013728}