blob: a7af8bab6fc8c638eb9c2f08bc9a21d8ee88d5d5 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700113import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.File;
125import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200129import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800130import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700135import java.util.Collections;
136import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700143import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700147public final class ActivityManagerService extends ActivityManagerNative
148 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "ActivityManager";
150 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400151 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_SWITCH = localLOGV || false;
153 static final boolean DEBUG_TASKS = localLOGV || false;
154 static final boolean DEBUG_PAUSE = localLOGV || false;
155 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156 static final boolean DEBUG_TRANSITION = localLOGV || false;
157 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700158 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700160 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_VISBILITY = localLOGV || false;
162 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700163 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800164 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700166 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700167 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700168 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final boolean DEBUG_POWER = localLOGV || false;
170 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean VALIDATE_TOKENS = false;
172 static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174 // Control over CPU and battery monitoring.
175 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
176 static final boolean MONITOR_CPU_USAGE = true;
177 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
178 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
179 static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700182 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800184 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 // Maximum number of recent tasks that we can remember.
187 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700188
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700189 // Amount of time after a call to stopAppSwitches() during which we will
190 // prevent further untrusted switches from happening.
191 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192
193 // How long we wait for a launched process to attach to the activity manager
194 // before we decide it's never going to come up for real.
195 static final int PROC_START_TIMEOUT = 10*1000;
196
Jeff Brown3f9dd282011-07-08 20:02:19 -0700197 // How long we wait for a launched process to attach to the activity manager
198 // before we decide it's never going to come up for real, when the process was
199 // started with a wrapper for instrumentation (such as Valgrind) because it
200 // could take much longer than usual.
201 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 // How long to wait after going idle before forcing apps to GC.
204 static final int GC_TIMEOUT = 5*1000;
205
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700206 // The minimum amount of time between successive GC requests for a process.
207 static final int GC_MIN_INTERVAL = 60*1000;
208
Dianne Hackborn287952c2010-09-22 22:34:31 -0700209 // The rate at which we check for apps using excessive power -- 15 mins.
210 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
211
212 // The minimum sample duration we will allow before deciding we have
213 // enough data on wake locks to start killing things.
214 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
215
216 // The minimum sample duration we will allow before deciding we have
217 // enough data on CPU usage to start killing things.
218 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 // How long we allow a receiver to run before giving up on it.
221 static final int BROADCAST_TIMEOUT = 10*1000;
222
223 // How long we wait for a service to finish executing.
224 static final int SERVICE_TIMEOUT = 20*1000;
225
226 // How long a service needs to be running until restarting its process
227 // is no longer considered to be a relaunch of the service.
228 static final int SERVICE_RESTART_DURATION = 5*1000;
229
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700230 // How long a service needs to be running until it will start back at
231 // SERVICE_RESTART_DURATION after being killed.
232 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
233
234 // Multiplying factor to increase restart duration time by, for each time
235 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
236 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
237
238 // The minimum amount of time between restarting services that we allow.
239 // That is, when multiple services are restarting, we won't allow each
240 // to restart less than this amount of time from the last one.
241 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 // Maximum amount of time for there to be no activity on a service before
244 // we consider it non-essential and allow its process to go on the
245 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700246 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247
248 // How long we wait until we timeout on key dispatching.
249 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 // How long we wait until we timeout on key dispatching during instrumentation.
252 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
253
Dan Egnor42471dd2010-01-07 17:25:22 -0800254 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255
256 static final String[] EMPTY_STRING_ARRAY = new String[0];
257
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700258 public ActivityStack mMainStack;
259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700261 * Description of a request to start a new activity, which has been held
262 * due to app switches being disabled.
263 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700264 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700265 ActivityRecord r;
266 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700267 Uri[] grantedUriPermissions;
268 int grantedMode;
269 boolean onlyIfNeeded;
270 }
271
272 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
273 = new ArrayList<PendingActivityLaunch>();
274
275 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 * List of all active broadcasts that are to be executed immediately
277 * (without waiting for another broadcast to finish). Currently this only
278 * contains broadcasts to registered receivers, to avoid spinning up
279 * a bunch of processes to execute IntentReceiver components.
280 */
281 final ArrayList<BroadcastRecord> mParallelBroadcasts
282 = new ArrayList<BroadcastRecord>();
283
284 /**
285 * List of all active broadcasts that are to be executed one at a time.
286 * The object at the top of the list is the currently activity broadcasts;
287 * those after it are waiting for the top to finish..
288 */
289 final ArrayList<BroadcastRecord> mOrderedBroadcasts
290 = new ArrayList<BroadcastRecord>();
291
292 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800293 * Historical data of past broadcasts, for debugging.
294 */
295 static final int MAX_BROADCAST_HISTORY = 100;
296 final BroadcastRecord[] mBroadcastHistory
297 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
298
299 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 * Set when we current have a BROADCAST_INTENT_MSG in flight.
301 */
302 boolean mBroadcastsScheduled = false;
303
304 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 * Activity we have told the window manager to have key focus.
306 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700307 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700308 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 * List of intents that were used to start the most recent tasks.
310 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
313 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700314 * Process management.
315 */
316 final ProcessList mProcessList = new ProcessList();
317
318 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 * All of the applications we currently have running organized by name.
320 * The keys are strings of the application package name (as
321 * returned by the package manager), and the keys are ApplicationRecord
322 * objects.
323 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325
326 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700327 * The currently running heavy-weight process, if any.
328 */
329 ProcessRecord mHeavyWeightProcess = null;
330
331 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 * The last time that various processes have crashed.
333 */
334 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
335
336 /**
337 * Set of applications that we consider to be bad, and will reject
338 * incoming broadcasts from (which the user has no control over).
339 * Processes are added to this set when they have crashed twice within
340 * a minimum amount of time; they are removed from it when they are
341 * later restarted (hopefully due to some user action). The value is the
342 * time it was added to the list.
343 */
344 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
345
346 /**
347 * All of the processes we currently have running organized by pid.
348 * The keys are the pid running the application.
349 *
350 * <p>NOTE: This object is protected by its own lock, NOT the global
351 * activity manager lock!
352 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700353 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354
355 /**
356 * All of the processes that have been forced to be foreground. The key
357 * is the pid of the caller who requested it (we hold a death
358 * link on it).
359 */
360 abstract class ForegroundToken implements IBinder.DeathRecipient {
361 int pid;
362 IBinder token;
363 }
364 final SparseArray<ForegroundToken> mForegroundProcesses
365 = new SparseArray<ForegroundToken>();
366
367 /**
368 * List of records for processes that someone had tried to start before the
369 * system was ready. We don't start them at that point, but ensure they
370 * are started by the time booting is complete.
371 */
372 final ArrayList<ProcessRecord> mProcessesOnHold
373 = new ArrayList<ProcessRecord>();
374
375 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 * List of persistent applications that are in the process
377 * of being started.
378 */
379 final ArrayList<ProcessRecord> mPersistentStartingProcesses
380 = new ArrayList<ProcessRecord>();
381
382 /**
383 * Processes that are being forcibly torn down.
384 */
385 final ArrayList<ProcessRecord> mRemovedProcesses
386 = new ArrayList<ProcessRecord>();
387
388 /**
389 * List of running applications, sorted by recent usage.
390 * The first entry in the list is the least recently used.
391 * It contains ApplicationRecord objects. This list does NOT include
392 * any persistent application records (since we never want to exit them).
393 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800394 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 = new ArrayList<ProcessRecord>();
396
397 /**
398 * List of processes that should gc as soon as things are idle.
399 */
400 final ArrayList<ProcessRecord> mProcessesToGc
401 = new ArrayList<ProcessRecord>();
402
403 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800404 * This is the process holding what we currently consider to be
405 * the "home" activity.
406 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700407 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800408
409 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400410 * Packages that the user has asked to have run in screen size
411 * compatibility mode instead of filling the screen.
412 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700413 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400414
415 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 * Set of PendingResultRecord objects that are currently active.
417 */
418 final HashSet mPendingResultRecords = new HashSet();
419
420 /**
421 * Set of IntentSenderRecord objects that are currently active.
422 */
423 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
424 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
425
426 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800427 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700428 * already logged DropBox entries for. Guarded by itself. If
429 * something (rogue user app) forces this over
430 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
431 */
432 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
433 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
434
435 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700436 * Strict Mode background batched logging state.
437 *
438 * The string buffer is guarded by itself, and its lock is also
439 * used to determine if another batched write is already
440 * in-flight.
441 */
442 private final StringBuilder mStrictModeBuffer = new StringBuilder();
443
444 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700445 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
446 */
447 private boolean mPendingBroadcastTimeoutMessage;
448
449 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 * Intent broadcast that we have tried to start, but are
451 * waiting for its application's process to be created. We only
452 * need one (instead of a list) because we always process broadcasts
453 * one at a time, so no others can be started while waiting for this
454 * one.
455 */
456 BroadcastRecord mPendingBroadcast = null;
457
458 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700459 * The receiver index that is pending, to restart the broadcast if needed.
460 */
461 int mPendingBroadcastRecvIndex;
462
463 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 * Keeps track of all IIntentReceivers that have been registered for
465 * broadcasts. Hash keys are the receiver IBinder, hash value is
466 * a ReceiverList.
467 */
468 final HashMap mRegisteredReceivers = new HashMap();
469
470 /**
471 * Resolver for broadcast intents to registered receivers.
472 * Holds BroadcastFilter (subclass of IntentFilter).
473 */
474 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
475 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
476 @Override
477 protected boolean allowFilterResult(
478 BroadcastFilter filter, List<BroadcastFilter> dest) {
479 IBinder target = filter.receiverList.receiver.asBinder();
480 for (int i=dest.size()-1; i>=0; i--) {
481 if (dest.get(i).receiverList.receiver.asBinder() == target) {
482 return false;
483 }
484 }
485 return true;
486 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700487
488 @Override
489 protected String packageForFilter(BroadcastFilter filter) {
490 return filter.packageName;
491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 };
493
494 /**
495 * State of all active sticky broadcasts. Keys are the action of the
496 * sticky Intent, values are an ArrayList of all broadcasted intents with
497 * that action (which should usually be one).
498 */
499 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
500 new HashMap<String, ArrayList<Intent>>();
501
502 /**
503 * All currently running services.
504 */
505 final HashMap<ComponentName, ServiceRecord> mServices =
506 new HashMap<ComponentName, ServiceRecord>();
507
508 /**
509 * All currently running services indexed by the Intent used to start them.
510 */
511 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
512 new HashMap<Intent.FilterComparison, ServiceRecord>();
513
514 /**
515 * All currently bound service connections. Keys are the IBinder of
516 * the client's IServiceConnection.
517 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700518 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
519 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520
521 /**
522 * List of services that we have been asked to start,
523 * but haven't yet been able to. It is used to hold start requests
524 * while waiting for their corresponding application thread to get
525 * going.
526 */
527 final ArrayList<ServiceRecord> mPendingServices
528 = new ArrayList<ServiceRecord>();
529
530 /**
531 * List of services that are scheduled to restart following a crash.
532 */
533 final ArrayList<ServiceRecord> mRestartingServices
534 = new ArrayList<ServiceRecord>();
535
536 /**
537 * List of services that are in the process of being stopped.
538 */
539 final ArrayList<ServiceRecord> mStoppingServices
540 = new ArrayList<ServiceRecord>();
541
542 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700543 * Backup/restore process management
544 */
545 String mBackupAppName = null;
546 BackupRecord mBackupTarget = null;
547
548 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 * List of PendingThumbnailsRecord objects of clients who are still
550 * waiting to receive all of the thumbnails for a task.
551 */
552 final ArrayList mPendingThumbnails = new ArrayList();
553
554 /**
555 * List of HistoryRecord objects that have been finished and must
556 * still report back to a pending thumbnail receiver.
557 */
558 final ArrayList mCancelledThumbnails = new ArrayList();
559
560 /**
561 * All of the currently running global content providers. Keys are a
562 * string containing the provider name and values are a
563 * ContentProviderRecord object containing the data about it. Note
564 * that a single provider may be published under multiple names, so
565 * there may be multiple entries here for a single one in mProvidersByClass.
566 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700567 final HashMap<String, ContentProviderRecord> mProvidersByName
568 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569
570 /**
571 * All of the currently running global content providers. Keys are a
572 * string containing the provider's implementation class and values are a
573 * ContentProviderRecord object containing the data about it.
574 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700575 final HashMap<String, ContentProviderRecord> mProvidersByClass
576 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577
578 /**
579 * List of content providers who have clients waiting for them. The
580 * application is currently being launched and the provider will be
581 * removed from this list once it is published.
582 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700583 final ArrayList<ContentProviderRecord> mLaunchingProviders
584 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585
586 /**
587 * Global set of specific Uri permissions that have been granted.
588 */
589 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
590 = new SparseArray<HashMap<Uri, UriPermission>>();
591
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800592 CoreSettingsObserver mCoreSettingsObserver;
593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 /**
595 * Thread-local storage used to carry caller permissions over through
596 * indirect content-provider access.
597 * @see #ActivityManagerService.openContentUri()
598 */
599 private class Identity {
600 public int pid;
601 public int uid;
602
603 Identity(int _pid, int _uid) {
604 pid = _pid;
605 uid = _uid;
606 }
607 }
608 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
609
610 /**
611 * All information we have collected about the runtime performance of
612 * any user id that can impact battery performance.
613 */
614 final BatteryStatsService mBatteryStatsService;
615
616 /**
617 * information about component usage
618 */
619 final UsageStatsService mUsageStatsService;
620
621 /**
622 * Current configuration information. HistoryRecord objects are given
623 * a reference to this object to indicate which configuration they are
624 * currently running in, so this object must be kept immutable.
625 */
626 Configuration mConfiguration = new Configuration();
627
628 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800629 * Current sequencing integer of the configuration, for skipping old
630 * configurations.
631 */
632 int mConfigurationSeq = 0;
633
634 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700635 * Hardware-reported OpenGLES version.
636 */
637 final int GL_ES_VERSION;
638
639 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 * List of initialization arguments to pass to all processes when binding applications to them.
641 * For example, references to the commonly used services.
642 */
643 HashMap<String, IBinder> mAppBindArgs;
644
645 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700646 * Temporary to avoid allocations. Protected by main lock.
647 */
648 final StringBuilder mStringBuilder = new StringBuilder(256);
649
650 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 * Used to control how we initialize the service.
652 */
653 boolean mStartRunning = false;
654 ComponentName mTopComponent;
655 String mTopAction;
656 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700657 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 boolean mSystemReady = false;
659 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700660 boolean mWaitingUpdate = false;
661 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700662 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700663 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664
665 Context mContext;
666
667 int mFactoryTest;
668
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700669 boolean mCheckedForSetup;
670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700672 * The time at which we will allow normal application switches again,
673 * after a call to {@link #stopAppSwitches()}.
674 */
675 long mAppSwitchesAllowedTime;
676
677 /**
678 * This is set to true after the first switch after mAppSwitchesAllowedTime
679 * is set; any switches after that will clear the time.
680 */
681 boolean mDidAppSwitch;
682
683 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700684 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700685 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700686 long mLastPowerCheckRealtime;
687
688 /**
689 * Last time (in uptime) at which we checked for power usage.
690 */
691 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700692
693 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 * Set while we are wanting to sleep, to prevent any
695 * activities from being started/resumed.
696 */
697 boolean mSleeping = false;
698
699 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700700 * Set if we are shutting down the system, similar to sleeping.
701 */
702 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703
704 /**
705 * Task identifier that activities are currently being started
706 * in. Incremented each time a new task is created.
707 * todo: Replace this with a TokenSpace class that generates non-repeating
708 * integers that won't wrap.
709 */
710 int mCurTask = 1;
711
712 /**
713 * Current sequence id for oom_adj computation traversal.
714 */
715 int mAdjSeq = 0;
716
717 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700718 * Current sequence id for process LRU updating.
719 */
720 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721
722 /**
723 * System monitoring: number of processes that died since the last
724 * N procs were started.
725 */
726 int[] mProcDeaths = new int[20];
727
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700728 /**
729 * This is set if we had to do a delayed dexopt of an app before launching
730 * it, to increasing the ANR timeouts in that case.
731 */
732 boolean mDidDexOpt;
733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 String mDebugApp = null;
735 boolean mWaitForDebugger = false;
736 boolean mDebugTransient = false;
737 String mOrigDebugApp = null;
738 boolean mOrigWaitForDebugger = false;
739 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700740 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700741 String mProfileApp = null;
742 ProcessRecord mProfileProc = null;
743 String mProfileFile;
744 ParcelFileDescriptor mProfileFd;
745 int mProfileType = 0;
746 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700748 final RemoteCallbackList<IActivityWatcher> mWatchers
749 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700750
751 final RemoteCallbackList<IProcessObserver> mProcessObservers
752 = new RemoteCallbackList<IProcessObserver>();
753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 /**
755 * Callback of last caller to {@link #requestPss}.
756 */
757 Runnable mRequestPssCallback;
758
759 /**
760 * Remaining processes for which we are waiting results from the last
761 * call to {@link #requestPss}.
762 */
763 final ArrayList<ProcessRecord> mRequestPssList
764 = new ArrayList<ProcessRecord>();
765
766 /**
767 * Runtime statistics collection thread. This object's lock is used to
768 * protect all related state.
769 */
770 final Thread mProcessStatsThread;
771
772 /**
773 * Used to collect process stats when showing not responding dialog.
774 * Protected by mProcessStatsThread.
775 */
776 final ProcessStats mProcessStats = new ProcessStats(
777 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700778 final AtomicLong mLastCpuTime = new AtomicLong(0);
779 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 long mLastWriteTime = 0;
782
783 /**
784 * Set to true after the system has finished booting.
785 */
786 boolean mBooted = false;
787
Dianne Hackborn7d608422011-08-07 16:24:18 -0700788 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700789 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790
791 WindowManagerService mWindowManager;
792
793 static ActivityManagerService mSelf;
794 static ActivityThread mSystemThread;
795
796 private final class AppDeathRecipient implements IBinder.DeathRecipient {
797 final ProcessRecord mApp;
798 final int mPid;
799 final IApplicationThread mAppThread;
800
801 AppDeathRecipient(ProcessRecord app, int pid,
802 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800803 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 TAG, "New death recipient " + this
805 + " for thread " + thread.asBinder());
806 mApp = app;
807 mPid = pid;
808 mAppThread = thread;
809 }
810
811 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800812 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 TAG, "Death received in " + this
814 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 synchronized(ActivityManagerService.this) {
816 appDiedLocked(mApp, mPid, mAppThread);
817 }
818 }
819 }
820
821 static final int SHOW_ERROR_MSG = 1;
822 static final int SHOW_NOT_RESPONDING_MSG = 2;
823 static final int SHOW_FACTORY_ERROR_MSG = 3;
824 static final int UPDATE_CONFIGURATION_MSG = 4;
825 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
826 static final int WAIT_FOR_DEBUGGER_MSG = 6;
827 static final int BROADCAST_INTENT_MSG = 7;
828 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 static final int SERVICE_TIMEOUT_MSG = 12;
830 static final int UPDATE_TIME_ZONE = 13;
831 static final int SHOW_UID_ERROR_MSG = 14;
832 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700834 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700835 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800836 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700837 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
838 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700839 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700840 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700841 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700842 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700843 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700844 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
845 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846
847 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700848 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849
850 final Handler mHandler = new Handler() {
851 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800852 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 //}
854
855 public void handleMessage(Message msg) {
856 switch (msg.what) {
857 case SHOW_ERROR_MSG: {
858 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 synchronized (ActivityManagerService.this) {
860 ProcessRecord proc = (ProcessRecord)data.get("app");
861 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800862 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 return;
864 }
865 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700866 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800867 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 d.show();
869 proc.crashDialog = d;
870 } else {
871 // The device is asleep, so just pretend that the user
872 // saw a crash dialog and hit "force quit".
873 res.set(0);
874 }
875 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700876
877 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 } break;
879 case SHOW_NOT_RESPONDING_MSG: {
880 synchronized (ActivityManagerService.this) {
881 HashMap data = (HashMap) msg.obj;
882 ProcessRecord proc = (ProcessRecord)data.get("app");
883 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800884 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 return;
886 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800887
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700888 Intent intent = new Intent("android.intent.action.ANR");
889 if (!mProcessesReady) {
890 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
891 }
892 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800893 null, null, 0, null, null, null,
894 false, false, MY_PID, Process.SYSTEM_UID);
895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700897 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 d.show();
899 proc.anrDialog = d;
900 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700901
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700902 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700904 case SHOW_STRICT_MODE_VIOLATION_MSG: {
905 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
906 synchronized (ActivityManagerService.this) {
907 ProcessRecord proc = (ProcessRecord) data.get("app");
908 if (proc == null) {
909 Slog.e(TAG, "App not found when showing strict mode dialog.");
910 break;
911 }
912 if (proc.crashDialog != null) {
913 Slog.e(TAG, "App already has strict mode dialog: " + proc);
914 return;
915 }
916 AppErrorResult res = (AppErrorResult) data.get("result");
917 if (!mSleeping && !mShuttingDown) {
918 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
919 d.show();
920 proc.crashDialog = d;
921 } else {
922 // The device is asleep, so just pretend that the user
923 // saw a crash dialog and hit "force quit".
924 res.set(0);
925 }
926 }
927 ensureBootCompleted();
928 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 case SHOW_FACTORY_ERROR_MSG: {
930 Dialog d = new FactoryErrorDialog(
931 mContext, msg.getData().getCharSequence("msg"));
932 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700933 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 } break;
935 case UPDATE_CONFIGURATION_MSG: {
936 final ContentResolver resolver = mContext.getContentResolver();
937 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
938 } break;
939 case GC_BACKGROUND_PROCESSES_MSG: {
940 synchronized (ActivityManagerService.this) {
941 performAppGcsIfAppropriateLocked();
942 }
943 } break;
944 case WAIT_FOR_DEBUGGER_MSG: {
945 synchronized (ActivityManagerService.this) {
946 ProcessRecord app = (ProcessRecord)msg.obj;
947 if (msg.arg1 != 0) {
948 if (!app.waitedForDebugger) {
949 Dialog d = new AppWaitingForDebuggerDialog(
950 ActivityManagerService.this,
951 mContext, app);
952 app.waitDialog = d;
953 app.waitedForDebugger = true;
954 d.show();
955 }
956 } else {
957 if (app.waitDialog != null) {
958 app.waitDialog.dismiss();
959 app.waitDialog = null;
960 }
961 }
962 }
963 } break;
964 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800965 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 TAG, "Received BROADCAST_INTENT_MSG");
967 processNextBroadcast(true);
968 } break;
969 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700970 synchronized (ActivityManagerService.this) {
971 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700975 if (mDidDexOpt) {
976 mDidDexOpt = false;
977 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
978 nmsg.obj = msg.obj;
979 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
980 return;
981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 serviceTimeout((ProcessRecord)msg.obj);
983 } break;
984 case UPDATE_TIME_ZONE: {
985 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800986 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
987 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 if (r.thread != null) {
989 try {
990 r.thread.updateTimeZone();
991 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800992 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 }
994 }
995 }
996 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700997 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700998 case CLEAR_DNS_CACHE: {
999 synchronized (ActivityManagerService.this) {
1000 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1001 ProcessRecord r = mLruProcesses.get(i);
1002 if (r.thread != null) {
1003 try {
1004 r.thread.clearDnsCache();
1005 } catch (RemoteException ex) {
1006 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1007 }
1008 }
1009 }
1010 }
1011 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001012 case UPDATE_HTTP_PROXY: {
1013 ProxyProperties proxy = (ProxyProperties)msg.obj;
1014 String host = "";
1015 String port = "";
1016 String exclList = "";
1017 if (proxy != null) {
1018 host = proxy.getHost();
1019 port = Integer.toString(proxy.getPort());
1020 exclList = proxy.getExclusionList();
1021 }
1022 synchronized (ActivityManagerService.this) {
1023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1024 ProcessRecord r = mLruProcesses.get(i);
1025 if (r.thread != null) {
1026 try {
1027 r.thread.setHttpProxy(host, port, exclList);
1028 } catch (RemoteException ex) {
1029 Slog.w(TAG, "Failed to update http proxy for: " +
1030 r.info.processName);
1031 }
1032 }
1033 }
1034 }
1035 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 case SHOW_UID_ERROR_MSG: {
1037 // XXX This is a temporary dialog, no need to localize.
1038 AlertDialog d = new BaseErrorDialog(mContext);
1039 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1040 d.setCancelable(false);
1041 d.setTitle("System UIDs Inconsistent");
1042 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001043 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1045 mUidAlert = d;
1046 d.show();
1047 } break;
1048 case IM_FEELING_LUCKY_MSG: {
1049 if (mUidAlert != null) {
1050 mUidAlert.dismiss();
1051 mUidAlert = null;
1052 }
1053 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001055 if (mDidDexOpt) {
1056 mDidDexOpt = false;
1057 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1058 nmsg.obj = msg.obj;
1059 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1060 return;
1061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 ProcessRecord app = (ProcessRecord)msg.obj;
1063 synchronized (ActivityManagerService.this) {
1064 processStartTimedOutLocked(app);
1065 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001066 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001067 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1068 synchronized (ActivityManagerService.this) {
1069 doPendingActivityLaunchesLocked(true);
1070 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001071 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001072 case KILL_APPLICATION_MSG: {
1073 synchronized (ActivityManagerService.this) {
1074 int uid = msg.arg1;
1075 boolean restart = (msg.arg2 == 1);
1076 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001077 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001078 }
1079 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001080 case FINALIZE_PENDING_INTENT_MSG: {
1081 ((PendingIntentRecord)msg.obj).completeFinalize();
1082 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001083 case POST_HEAVY_NOTIFICATION_MSG: {
1084 INotificationManager inm = NotificationManager.getService();
1085 if (inm == null) {
1086 return;
1087 }
1088
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001089 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001090 ProcessRecord process = root.app;
1091 if (process == null) {
1092 return;
1093 }
1094
1095 try {
1096 Context context = mContext.createPackageContext(process.info.packageName, 0);
1097 String text = mContext.getString(R.string.heavy_weight_notification,
1098 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1099 Notification notification = new Notification();
1100 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1101 notification.when = 0;
1102 notification.flags = Notification.FLAG_ONGOING_EVENT;
1103 notification.tickerText = text;
1104 notification.defaults = 0; // please be quiet
1105 notification.sound = null;
1106 notification.vibrate = null;
1107 notification.setLatestEventInfo(context, text,
1108 mContext.getText(R.string.heavy_weight_notification_detail),
1109 PendingIntent.getActivity(mContext, 0, root.intent,
1110 PendingIntent.FLAG_CANCEL_CURRENT));
1111
1112 try {
1113 int[] outId = new int[1];
1114 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1115 notification, outId);
1116 } catch (RuntimeException e) {
1117 Slog.w(ActivityManagerService.TAG,
1118 "Error showing notification for heavy-weight app", e);
1119 } catch (RemoteException e) {
1120 }
1121 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001122 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001123 }
1124 } break;
1125 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1126 INotificationManager inm = NotificationManager.getService();
1127 if (inm == null) {
1128 return;
1129 }
1130 try {
1131 inm.cancelNotification("android",
1132 R.string.heavy_weight_notification);
1133 } catch (RuntimeException e) {
1134 Slog.w(ActivityManagerService.TAG,
1135 "Error canceling notification for service", e);
1136 } catch (RemoteException e) {
1137 }
1138 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001139 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1140 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001141 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001142 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001143 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1144 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001145 }
1146 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001147 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1148 synchronized (ActivityManagerService.this) {
1149 ActivityRecord ar = (ActivityRecord)msg.obj;
1150 if (mCompatModeDialog != null) {
1151 if (mCompatModeDialog.mAppInfo.packageName.equals(
1152 ar.info.applicationInfo.packageName)) {
1153 return;
1154 }
1155 mCompatModeDialog.dismiss();
1156 mCompatModeDialog = null;
1157 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001158 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001159 if (mCompatModePackages.getPackageAskCompatModeLocked(
1160 ar.packageName)) {
1161 int mode = mCompatModePackages.computeCompatModeLocked(
1162 ar.info.applicationInfo);
1163 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1164 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1165 mCompatModeDialog = new CompatModeDialog(
1166 ActivityManagerService.this, mContext,
1167 ar.info.applicationInfo);
1168 mCompatModeDialog.show();
1169 }
1170 }
1171 }
1172 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001173 break;
1174 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001175 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001176 final int pid = msg.arg1;
1177 final int uid = msg.arg2;
1178 final boolean foregroundActivities = (Boolean) msg.obj;
1179 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001180 break;
1181 }
1182 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001183 final int pid = msg.arg1;
1184 final int uid = msg.arg2;
1185 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001186 break;
1187 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001188 }
1189 }
1190 };
1191
1192 public static void setSystemProcess() {
1193 try {
1194 ActivityManagerService m = mSelf;
1195
1196 ServiceManager.addService("activity", m);
1197 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001198 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001199 if (MONITOR_CPU_USAGE) {
1200 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001202 ServiceManager.addService("permission", new PermissionController(m));
1203
1204 ApplicationInfo info =
1205 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001206 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001207 mSystemThread.installSystemApplicationInfo(info);
1208
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 synchronized (mSelf) {
1210 ProcessRecord app = mSelf.newProcessRecordLocked(
1211 mSystemThread.getApplicationThread(), info,
1212 info.processName);
1213 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001214 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001215 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1217 synchronized (mSelf.mPidsSelfLocked) {
1218 mSelf.mPidsSelfLocked.put(app.pid, app);
1219 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001220 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 }
1222 } catch (PackageManager.NameNotFoundException e) {
1223 throw new RuntimeException(
1224 "Unable to find android system package", e);
1225 }
1226 }
1227
1228 public void setWindowManager(WindowManagerService wm) {
1229 mWindowManager = wm;
1230 }
1231
1232 public static final Context main(int factoryTest) {
1233 AThread thr = new AThread();
1234 thr.start();
1235
1236 synchronized (thr) {
1237 while (thr.mService == null) {
1238 try {
1239 thr.wait();
1240 } catch (InterruptedException e) {
1241 }
1242 }
1243 }
1244
1245 ActivityManagerService m = thr.mService;
1246 mSelf = m;
1247 ActivityThread at = ActivityThread.systemMain();
1248 mSystemThread = at;
1249 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001250 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 m.mContext = context;
1252 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001253 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254
1255 m.mBatteryStatsService.publish(context);
1256 m.mUsageStatsService.publish(context);
1257
1258 synchronized (thr) {
1259 thr.mReady = true;
1260 thr.notifyAll();
1261 }
1262
1263 m.startRunning(null, null, null, null);
1264
1265 return context;
1266 }
1267
1268 public static ActivityManagerService self() {
1269 return mSelf;
1270 }
1271
1272 static class AThread extends Thread {
1273 ActivityManagerService mService;
1274 boolean mReady = false;
1275
1276 public AThread() {
1277 super("ActivityManager");
1278 }
1279
1280 public void run() {
1281 Looper.prepare();
1282
1283 android.os.Process.setThreadPriority(
1284 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001285 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286
1287 ActivityManagerService m = new ActivityManagerService();
1288
1289 synchronized (this) {
1290 mService = m;
1291 notifyAll();
1292 }
1293
1294 synchronized (this) {
1295 while (!mReady) {
1296 try {
1297 wait();
1298 } catch (InterruptedException e) {
1299 }
1300 }
1301 }
1302
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001303 // For debug builds, log event loop stalls to dropbox for analysis.
1304 if (StrictMode.conditionallyEnableDebugLogging()) {
1305 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1306 }
1307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 Looper.loop();
1309 }
1310 }
1311
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 static class MemBinder extends Binder {
1313 ActivityManagerService mActivityManagerService;
1314 MemBinder(ActivityManagerService activityManagerService) {
1315 mActivityManagerService = activityManagerService;
1316 }
1317
1318 @Override
1319 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001320 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 }
1322 }
1323
Chet Haase9c1e23b2011-03-24 10:51:31 -07001324 static class GraphicsBinder extends Binder {
1325 ActivityManagerService mActivityManagerService;
1326 GraphicsBinder(ActivityManagerService activityManagerService) {
1327 mActivityManagerService = activityManagerService;
1328 }
1329
1330 @Override
1331 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001332 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001333 }
1334 }
1335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 static class CpuBinder extends Binder {
1337 ActivityManagerService mActivityManagerService;
1338 CpuBinder(ActivityManagerService activityManagerService) {
1339 mActivityManagerService = activityManagerService;
1340 }
1341
1342 @Override
1343 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1344 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001345 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1346 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1347 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 }
1349 }
1350 }
1351
1352 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001353 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 File dataDir = Environment.getDataDirectory();
1356 File systemDir = new File(dataDir, "system");
1357 systemDir.mkdirs();
1358 mBatteryStatsService = new BatteryStatsService(new File(
1359 systemDir, "batterystats.bin").toString());
1360 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001361 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001362 mOnBattery = DEBUG_POWER ? true
1363 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001364 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001366 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001367 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368
Jack Palevichb90d28c2009-07-22 15:35:24 -07001369 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1370 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1371
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001372 mConfiguration.setToDefaults();
1373 mConfiguration.locale = Locale.getDefault();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001374 mProcessStats.init();
1375
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001376 mCompatModePackages = new CompatModePackages(this, systemDir);
1377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 // Add ourself to the Watchdog monitors.
1379 Watchdog.getInstance().addMonitor(this);
1380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001381 mProcessStatsThread = new Thread("ProcessStats") {
1382 public void run() {
1383 while (true) {
1384 try {
1385 try {
1386 synchronized(this) {
1387 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001388 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001390 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391 // + ", write delay=" + nextWriteDelay);
1392 if (nextWriteDelay < nextCpuDelay) {
1393 nextCpuDelay = nextWriteDelay;
1394 }
1395 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001396 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 this.wait(nextCpuDelay);
1398 }
1399 }
1400 } catch (InterruptedException e) {
1401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001402 updateCpuStatsNow();
1403 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001404 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 }
1406 }
1407 }
1408 };
1409 mProcessStatsThread.start();
1410 }
1411
1412 @Override
1413 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1414 throws RemoteException {
1415 try {
1416 return super.onTransact(code, data, reply, flags);
1417 } catch (RuntimeException e) {
1418 // The activity manager only throws security exceptions, so let's
1419 // log all others.
1420 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001421 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 }
1423 throw e;
1424 }
1425 }
1426
1427 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001428 final long now = SystemClock.uptimeMillis();
1429 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1430 return;
1431 }
1432 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1433 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 mProcessStatsThread.notify();
1435 }
1436 }
1437 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 void updateCpuStatsNow() {
1440 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001441 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 final long now = SystemClock.uptimeMillis();
1443 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001446 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1447 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448 haveNewCpuStats = true;
1449 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001450 //Slog.i(TAG, mProcessStats.printCurrentState());
1451 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 // + mProcessStats.getTotalCpuPercent() + "%");
1453
Joe Onorato8a9b2202010-02-26 18:56:32 -08001454 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 if ("true".equals(SystemProperties.get("events.cpu"))) {
1456 int user = mProcessStats.getLastUserTime();
1457 int system = mProcessStats.getLastSystemTime();
1458 int iowait = mProcessStats.getLastIoWaitTime();
1459 int irq = mProcessStats.getLastIrqTime();
1460 int softIrq = mProcessStats.getLastSoftIrqTime();
1461 int idle = mProcessStats.getLastIdleTime();
1462
1463 int total = user + system + iowait + irq + softIrq + idle;
1464 if (total == 0) total = 1;
1465
Doug Zongker2bec3d42009-12-04 12:52:44 -08001466 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 ((user+system+iowait+irq+softIrq) * 100) / total,
1468 (user * 100) / total,
1469 (system * 100) / total,
1470 (iowait * 100) / total,
1471 (irq * 100) / total,
1472 (softIrq * 100) / total);
1473 }
1474 }
1475
Amith Yamasanie43530a2009-08-21 13:11:37 -07001476 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001477 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001478 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001479 synchronized(mPidsSelfLocked) {
1480 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001481 if (mOnBattery) {
1482 int perc = bstats.startAddingCpuLocked();
1483 int totalUTime = 0;
1484 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001485 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001487 ProcessStats.Stats st = mProcessStats.getStats(i);
1488 if (!st.working) {
1489 continue;
1490 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001492 int otherUTime = (st.rel_utime*perc)/100;
1493 int otherSTime = (st.rel_stime*perc)/100;
1494 totalUTime += otherUTime;
1495 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 if (pr != null) {
1497 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001498 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1499 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001500 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001501 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001502 } else {
1503 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001504 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001505 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001506 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1507 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001508 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 }
1511 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001512 bstats.finishAddingCpuLocked(perc, totalUTime,
1513 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 }
1515 }
1516 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001518 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1519 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001520 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 }
1522 }
1523 }
1524 }
1525
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001526 @Override
1527 public void batteryNeedsCpuUpdate() {
1528 updateCpuStatsNow();
1529 }
1530
1531 @Override
1532 public void batteryPowerChanged(boolean onBattery) {
1533 // When plugging in, update the CPU stats first before changing
1534 // the plug state.
1535 updateCpuStatsNow();
1536 synchronized (this) {
1537 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001538 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001539 }
1540 }
1541 }
1542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 /**
1544 * Initialize the application bind args. These are passed to each
1545 * process when the bindApplication() IPC is sent to the process. They're
1546 * lazily setup to make sure the services are running when they're asked for.
1547 */
1548 private HashMap<String, IBinder> getCommonServicesLocked() {
1549 if (mAppBindArgs == null) {
1550 mAppBindArgs = new HashMap<String, IBinder>();
1551
1552 // Setup the application init args
1553 mAppBindArgs.put("package", ServiceManager.getService("package"));
1554 mAppBindArgs.put("window", ServiceManager.getService("window"));
1555 mAppBindArgs.put(Context.ALARM_SERVICE,
1556 ServiceManager.getService(Context.ALARM_SERVICE));
1557 }
1558 return mAppBindArgs;
1559 }
1560
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001561 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 if (mFocusedActivity != r) {
1563 mFocusedActivity = r;
1564 mWindowManager.setFocusedApp(r, true);
1565 }
1566 }
1567
Dianne Hackborn906497c2010-05-10 15:57:38 -07001568 private final void updateLruProcessInternalLocked(ProcessRecord app,
1569 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001571 int lrui = mLruProcesses.indexOf(app);
1572 if (lrui >= 0) mLruProcesses.remove(lrui);
1573
1574 int i = mLruProcesses.size()-1;
1575 int skipTop = 0;
1576
Dianne Hackborn906497c2010-05-10 15:57:38 -07001577 app.lruSeq = mLruSeq;
1578
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001579 // compute the new weight for this process.
1580 if (updateActivityTime) {
1581 app.lastActivityTime = SystemClock.uptimeMillis();
1582 }
1583 if (app.activities.size() > 0) {
1584 // If this process has activities, we more strongly want to keep
1585 // it around.
1586 app.lruWeight = app.lastActivityTime;
1587 } else if (app.pubProviders.size() > 0) {
1588 // If this process contains content providers, we want to keep
1589 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001590 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001591 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001592 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001593 } else {
1594 // If this process doesn't have activities, we less strongly
1595 // want to keep it around, and generally want to avoid getting
1596 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001597 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001598 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001599 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001600 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001601
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001602 while (i >= 0) {
1603 ProcessRecord p = mLruProcesses.get(i);
1604 // If this app shouldn't be in front of the first N background
1605 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001606 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001607 skipTop--;
1608 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001609 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001610 mLruProcesses.add(i+1, app);
1611 break;
1612 }
1613 i--;
1614 }
1615 if (i < 0) {
1616 mLruProcesses.add(0, app);
1617 }
1618
Dianne Hackborn906497c2010-05-10 15:57:38 -07001619 // If the app is currently using a content provider or service,
1620 // bump those processes as well.
1621 if (app.connections.size() > 0) {
1622 for (ConnectionRecord cr : app.connections) {
1623 if (cr.binding != null && cr.binding.service != null
1624 && cr.binding.service.app != null
1625 && cr.binding.service.app.lruSeq != mLruSeq) {
1626 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1627 updateActivityTime, i+1);
1628 }
1629 }
1630 }
1631 if (app.conProviders.size() > 0) {
1632 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
1633 if (cpr.app != null && cpr.app.lruSeq != mLruSeq) {
1634 updateLruProcessInternalLocked(cpr.app, oomAdj,
1635 updateActivityTime, i+1);
1636 }
1637 }
1638 }
1639
Joe Onorato8a9b2202010-02-26 18:56:32 -08001640 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 if (oomAdj) {
1642 updateOomAdjLocked();
1643 }
1644 }
1645
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001646 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001647 boolean oomAdj, boolean updateActivityTime) {
1648 mLruSeq++;
1649 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1650 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001651
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001652 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001653 String processName, int uid) {
1654 if (uid == Process.SYSTEM_UID) {
1655 // The system gets to run in any process. If there are multiple
1656 // processes with the same uid, just pick the first (this
1657 // should never happen).
1658 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1659 processName);
1660 return procs != null ? procs.valueAt(0) : null;
1661 }
1662 ProcessRecord proc = mProcessNames.get(processName, uid);
1663 return proc;
1664 }
1665
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001666 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001667 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001668 try {
1669 if (pm.performDexOpt(packageName)) {
1670 mDidDexOpt = true;
1671 }
1672 } catch (RemoteException e) {
1673 }
1674 }
1675
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001676 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001677 int transit = mWindowManager.getPendingAppTransition();
1678 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1679 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1680 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1681 }
1682
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001683 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001684 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001685 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1687 // We don't have to do anything more if:
1688 // (1) There is an existing application record; and
1689 // (2) The caller doesn't think it is dead, OR there is no thread
1690 // object attached to it so we know it couldn't have crashed; and
1691 // (3) There is a pid assigned to it, so it is either starting or
1692 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001693 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694 + " app=" + app + " knownToBeDead=" + knownToBeDead
1695 + " thread=" + (app != null ? app.thread : null)
1696 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001697 if (app != null && app.pid > 0) {
1698 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001699 // We already have the app running, or are waiting for it to
1700 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001701 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001702 // If this is a new package in the process, add the package to the list
1703 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001704 return app;
1705 } else {
1706 // An application record is attached to a previous process,
1707 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001708 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001709 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001710 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001711 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 String hostingNameStr = hostingName != null
1714 ? hostingName.flattenToShortString() : null;
1715
1716 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1717 // If we are in the background, then check to see if this process
1718 // is bad. If so, we will just silently fail.
1719 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001720 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1721 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 return null;
1723 }
1724 } else {
1725 // When the user is explicitly starting a process, then clear its
1726 // crash count so that we won't make it bad until they see at
1727 // least one crash dialog again, and make the process good again
1728 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001729 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1730 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001731 mProcessCrashTimes.remove(info.processName, info.uid);
1732 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001733 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001734 info.processName);
1735 mBadProcesses.remove(info.processName, info.uid);
1736 if (app != null) {
1737 app.bad = false;
1738 }
1739 }
1740 }
1741
1742 if (app == null) {
1743 app = newProcessRecordLocked(null, info, processName);
1744 mProcessNames.put(processName, info.uid, app);
1745 } else {
1746 // If this is a new package in the process, add the package to the list
1747 app.addPackage(info.packageName);
1748 }
1749
1750 // If the system is not ready yet, then hold off on starting this
1751 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001752 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001753 && !isAllowedWhileBooting(info)
1754 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001755 if (!mProcessesOnHold.contains(app)) {
1756 mProcessesOnHold.add(app);
1757 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001758 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 return app;
1760 }
1761
1762 startProcessLocked(app, hostingType, hostingNameStr);
1763 return (app.pid != 0) ? app : null;
1764 }
1765
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001766 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1767 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1768 }
1769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770 private final void startProcessLocked(ProcessRecord app,
1771 String hostingType, String hostingNameStr) {
1772 if (app.pid > 0 && app.pid != MY_PID) {
1773 synchronized (mPidsSelfLocked) {
1774 mPidsSelfLocked.remove(app.pid);
1775 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1776 }
1777 app.pid = 0;
1778 }
1779
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001780 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1781 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 mProcessesOnHold.remove(app);
1783
1784 updateCpuStats();
1785
1786 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1787 mProcDeaths[0] = 0;
1788
1789 try {
1790 int uid = app.info.uid;
1791 int[] gids = null;
1792 try {
1793 gids = mContext.getPackageManager().getPackageGids(
1794 app.info.packageName);
1795 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001796 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001797 }
1798 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1799 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1800 && mTopComponent != null
1801 && app.processName.equals(mTopComponent.getPackageName())) {
1802 uid = 0;
1803 }
1804 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1805 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1806 uid = 0;
1807 }
1808 }
1809 int debugFlags = 0;
1810 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1811 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001812 // Also turn on CheckJNI for debuggable apps. It's quite
1813 // awkward to turn on otherwise.
1814 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001815 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001816 // Run the app in safe mode if its manifest requests so or the
1817 // system is booted in safe mode.
1818 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1819 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001820 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1821 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001822 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1823 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1824 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001825 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1826 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001828 if ("1".equals(SystemProperties.get("debug.assert"))) {
1829 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1830 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001831
1832 // Start the process. It will either succeed and return a result containing
1833 // the PID of the new process, or else throw a RuntimeException.
1834 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001835 app.processName, uid, uid, gids, debugFlags,
1836 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1839 synchronized (bs) {
1840 if (bs.isOnBattery()) {
1841 app.batteryStats.incStartsLocked();
1842 }
1843 }
1844
Jeff Brown3f9dd282011-07-08 20:02:19 -07001845 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 app.processName, hostingType,
1847 hostingNameStr != null ? hostingNameStr : "");
1848
1849 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001850 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001851 }
1852
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001853 StringBuilder buf = mStringBuilder;
1854 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001855 buf.append("Start proc ");
1856 buf.append(app.processName);
1857 buf.append(" for ");
1858 buf.append(hostingType);
1859 if (hostingNameStr != null) {
1860 buf.append(" ");
1861 buf.append(hostingNameStr);
1862 }
1863 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001864 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001865 buf.append(" uid=");
1866 buf.append(uid);
1867 buf.append(" gids={");
1868 if (gids != null) {
1869 for (int gi=0; gi<gids.length; gi++) {
1870 if (gi != 0) buf.append(", ");
1871 buf.append(gids[gi]);
1872
1873 }
1874 }
1875 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08001876 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07001877 app.pid = startResult.pid;
1878 app.usingWrapper = startResult.usingWrapper;
1879 app.removed = false;
1880 synchronized (mPidsSelfLocked) {
1881 this.mPidsSelfLocked.put(startResult.pid, app);
1882 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1883 msg.obj = app;
1884 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
1885 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 }
1887 } catch (RuntimeException e) {
1888 // XXX do better error recovery.
1889 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001890 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001891 }
1892 }
1893
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001894 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 if (resumed) {
1896 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
1897 } else {
1898 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
1899 }
1900 }
1901
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001902 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001903 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1904 && mTopAction == null) {
1905 // We are running in factory test mode, but unable to find
1906 // the factory test app, so just sit around displaying the
1907 // error message and don't try to start anything.
1908 return false;
1909 }
1910 Intent intent = new Intent(
1911 mTopAction,
1912 mTopData != null ? Uri.parse(mTopData) : null);
1913 intent.setComponent(mTopComponent);
1914 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
1915 intent.addCategory(Intent.CATEGORY_HOME);
1916 }
1917 ActivityInfo aInfo =
1918 intent.resolveActivityInfo(mContext.getPackageManager(),
1919 STOCK_PM_FLAGS);
1920 if (aInfo != null) {
1921 intent.setComponent(new ComponentName(
1922 aInfo.applicationInfo.packageName, aInfo.name));
1923 // Don't do this if the home app is currently being
1924 // instrumented.
1925 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
1926 aInfo.applicationInfo.uid);
1927 if (app == null || app.instrumentationClass == null) {
1928 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001929 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001930 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001931 }
1932 }
1933
1934
1935 return true;
1936 }
1937
1938 /**
1939 * Starts the "new version setup screen" if appropriate.
1940 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001941 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001942 // Only do this once per boot.
1943 if (mCheckedForSetup) {
1944 return;
1945 }
1946
1947 // We will show this screen if the current one is a different
1948 // version than the last one shown, and we are not running in
1949 // low-level factory test mode.
1950 final ContentResolver resolver = mContext.getContentResolver();
1951 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
1952 Settings.Secure.getInt(resolver,
1953 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
1954 mCheckedForSetup = true;
1955
1956 // See if we should be showing the platform update setup UI.
1957 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
1958 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
1959 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
1960
1961 // We don't allow third party apps to replace this.
1962 ResolveInfo ri = null;
1963 for (int i=0; ris != null && i<ris.size(); i++) {
1964 if ((ris.get(i).activityInfo.applicationInfo.flags
1965 & ApplicationInfo.FLAG_SYSTEM) != 0) {
1966 ri = ris.get(i);
1967 break;
1968 }
1969 }
1970
1971 if (ri != null) {
1972 String vers = ri.activityInfo.metaData != null
1973 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
1974 : null;
1975 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
1976 vers = ri.activityInfo.applicationInfo.metaData.getString(
1977 Intent.METADATA_SETUP_VERSION);
1978 }
1979 String lastVers = Settings.Secure.getString(
1980 resolver, Settings.Secure.LAST_SETUP_SHOWN);
1981 if (vers != null && !vers.equals(lastVers)) {
1982 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
1983 intent.setComponent(new ComponentName(
1984 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001985 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08001986 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07001987 }
1988 }
1989 }
1990 }
1991
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001992 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001993 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001994 }
1995
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001996 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001997 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001998 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
1999 }
2000 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002001
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002002 public void setFrontActivityScreenCompatMode(int mode) {
2003 synchronized (this) {
2004 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2005 }
2006 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002007
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002008 public int getPackageScreenCompatMode(String packageName) {
2009 synchronized (this) {
2010 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2011 }
2012 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002013
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002014 public void setPackageScreenCompatMode(String packageName, int mode) {
2015 synchronized (this) {
2016 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002017 }
2018 }
2019
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002020 public boolean getPackageAskScreenCompat(String packageName) {
2021 synchronized (this) {
2022 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2023 }
2024 }
2025
2026 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2027 synchronized (this) {
2028 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2029 }
2030 }
2031
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002032 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002033 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002034
2035 final int identHash = System.identityHashCode(r);
2036 updateUsageStats(r, true);
2037
2038 int i = mWatchers.beginBroadcast();
2039 while (i > 0) {
2040 i--;
2041 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2042 if (w != null) {
2043 try {
2044 w.activityResuming(identHash);
2045 } catch (RemoteException e) {
2046 }
2047 }
2048 }
2049 mWatchers.finishBroadcast();
2050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051
Jeff Sharkeya4620792011-05-20 15:29:23 -07002052 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2053 int i = mProcessObservers.beginBroadcast();
2054 while (i > 0) {
2055 i--;
2056 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2057 if (observer != null) {
2058 try {
2059 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2060 } catch (RemoteException e) {
2061 }
2062 }
2063 }
2064 mProcessObservers.finishBroadcast();
2065 }
2066
2067 private void dispatchProcessDied(int pid, int uid) {
2068 int i = mProcessObservers.beginBroadcast();
2069 while (i > 0) {
2070 i--;
2071 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2072 if (observer != null) {
2073 try {
2074 observer.onProcessDied(pid, uid);
2075 } catch (RemoteException e) {
2076 }
2077 }
2078 }
2079 mProcessObservers.finishBroadcast();
2080 }
2081
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002082 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002083 final int N = mPendingActivityLaunches.size();
2084 if (N <= 0) {
2085 return;
2086 }
2087 for (int i=0; i<N; i++) {
2088 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002089 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002090 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2091 doResume && i == (N-1));
2092 }
2093 mPendingActivityLaunches.clear();
2094 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002095
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002096 public final int startActivity(IApplicationThread caller,
2097 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2098 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002099 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2100 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002101 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002102 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002103 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2104 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002105 }
2106
2107 public final WaitResult startActivityAndWait(IApplicationThread caller,
2108 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2109 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002110 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2111 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002112 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002113 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002114 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002115 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2116 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002117 return res;
2118 }
2119
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002120 public final int startActivityWithConfig(IApplicationThread caller,
2121 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2122 int grantedMode, IBinder resultTo,
2123 String resultWho, int requestCode, boolean onlyIfNeeded,
2124 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002125 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002126 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002127 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002128 }
2129
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002130 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002131 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002132 IBinder resultTo, String resultWho, int requestCode,
2133 int flagsMask, int flagsValues) {
2134 // Refuse possible leaked file descriptors
2135 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2136 throw new IllegalArgumentException("File descriptors passed in Intent");
2137 }
2138
2139 IIntentSender sender = intent.getTarget();
2140 if (!(sender instanceof PendingIntentRecord)) {
2141 throw new IllegalArgumentException("Bad PendingIntent object");
2142 }
2143
2144 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002145
2146 synchronized (this) {
2147 // If this is coming from the currently resumed activity, it is
2148 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002149 if (mMainStack.mResumedActivity != null
2150 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002151 Binder.getCallingUid()) {
2152 mAppSwitchesAllowedTime = 0;
2153 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002154 }
2155
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002156 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002157 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2158 }
2159
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002160 public boolean startNextMatchingActivity(IBinder callingActivity,
2161 Intent intent) {
2162 // Refuse possible leaked file descriptors
2163 if (intent != null && intent.hasFileDescriptors() == true) {
2164 throw new IllegalArgumentException("File descriptors passed in Intent");
2165 }
2166
2167 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002168 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2169 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170 return false;
2171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 if (r.app == null || r.app.thread == null) {
2173 // The caller is not running... d'oh!
2174 return false;
2175 }
2176 intent = new Intent(intent);
2177 // The caller is not allowed to change the data.
2178 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2179 // And we are resetting to find the next component...
2180 intent.setComponent(null);
2181
2182 ActivityInfo aInfo = null;
2183 try {
2184 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002185 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002186 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002187 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002188
2189 // Look for the original activity in the list...
2190 final int N = resolves != null ? resolves.size() : 0;
2191 for (int i=0; i<N; i++) {
2192 ResolveInfo rInfo = resolves.get(i);
2193 if (rInfo.activityInfo.packageName.equals(r.packageName)
2194 && rInfo.activityInfo.name.equals(r.info.name)) {
2195 // We found the current one... the next matching is
2196 // after it.
2197 i++;
2198 if (i<N) {
2199 aInfo = resolves.get(i).activityInfo;
2200 }
2201 break;
2202 }
2203 }
2204 } catch (RemoteException e) {
2205 }
2206
2207 if (aInfo == null) {
2208 // Nobody who is next!
2209 return false;
2210 }
2211
2212 intent.setComponent(new ComponentName(
2213 aInfo.applicationInfo.packageName, aInfo.name));
2214 intent.setFlags(intent.getFlags()&~(
2215 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2216 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2217 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2218 Intent.FLAG_ACTIVITY_NEW_TASK));
2219
2220 // Okay now we need to start the new activity, replacing the
2221 // currently running activity. This is a little tricky because
2222 // we want to start the new one as if the current one is finished,
2223 // but not finish the current one first so that there is no flicker.
2224 // And thus...
2225 final boolean wasFinishing = r.finishing;
2226 r.finishing = true;
2227
2228 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002229 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 final String resultWho = r.resultWho;
2231 final int requestCode = r.requestCode;
2232 r.resultTo = null;
2233 if (resultTo != null) {
2234 resultTo.removeResultsLocked(r, resultWho, requestCode);
2235 }
2236
2237 final long origId = Binder.clearCallingIdentity();
2238 // XXX we are not dealing with propagating grantedUriPermissions...
2239 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002240 int res = mMainStack.startActivityLocked(r.app.thread, intent,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 r.resolvedType, null, 0, aInfo, resultTo, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002242 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 Binder.restoreCallingIdentity(origId);
2244
2245 r.finishing = wasFinishing;
2246 if (res != START_SUCCESS) {
2247 return false;
2248 }
2249 return true;
2250 }
2251 }
2252
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002253 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 Intent intent, String resolvedType, IBinder resultTo,
2255 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002256
2257 // This is so super not safe, that only the system (or okay root)
2258 // can do it.
2259 final int callingUid = Binder.getCallingUid();
2260 if (callingUid != 0 && callingUid != Process.myUid()) {
2261 throw new SecurityException(
2262 "startActivityInPackage only available to the system");
2263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002265 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002266 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2267 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002268 }
2269
2270 public final int startActivities(IApplicationThread caller,
2271 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2272 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2273 }
2274
2275 public final int startActivitiesInPackage(int uid,
2276 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2277
2278 // This is so super not safe, that only the system (or okay root)
2279 // can do it.
2280 final int callingUid = Binder.getCallingUid();
2281 if (callingUid != 0 && callingUid != Process.myUid()) {
2282 throw new SecurityException(
2283 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 }
2285
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002286 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002287 }
2288
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002289 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002291 // Quick case: check if the top-most recent task is the same.
2292 if (N > 0 && mRecentTasks.get(0) == task) {
2293 return;
2294 }
2295 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 for (int i=0; i<N; i++) {
2297 TaskRecord tr = mRecentTasks.get(i);
2298 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2299 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2300 mRecentTasks.remove(i);
2301 i--;
2302 N--;
2303 if (task.intent == null) {
2304 // If the new recent task we are adding is not fully
2305 // specified, then replace it with the existing recent task.
2306 task = tr;
2307 }
2308 }
2309 }
2310 if (N >= MAX_RECENT_TASKS) {
2311 mRecentTasks.remove(N-1);
2312 }
2313 mRecentTasks.add(0, task);
2314 }
2315
2316 public void setRequestedOrientation(IBinder token,
2317 int requestedOrientation) {
2318 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002319 ActivityRecord r = mMainStack.isInStackLocked(token);
2320 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 return;
2322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 final long origId = Binder.clearCallingIdentity();
2324 mWindowManager.setAppOrientation(r, requestedOrientation);
2325 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002326 mConfiguration,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 r.mayFreezeScreenLocked(r.app) ? r : null);
2328 if (config != null) {
2329 r.frozenBeforeDestroy = true;
Dianne Hackborn31ca8542011-07-19 14:58:28 -07002330 if (!updateConfigurationLocked(config, r, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002331 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002332 }
2333 }
2334 Binder.restoreCallingIdentity(origId);
2335 }
2336 }
2337
2338 public int getRequestedOrientation(IBinder token) {
2339 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002340 ActivityRecord r = mMainStack.isInStackLocked(token);
2341 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002342 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344 return mWindowManager.getAppOrientation(r);
2345 }
2346 }
2347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 /**
2349 * This is the internal entry point for handling Activity.finish().
2350 *
2351 * @param token The Binder token referencing the Activity we want to finish.
2352 * @param resultCode Result code, if any, from this Activity.
2353 * @param resultData Result data (Intent), if any, from this Activity.
2354 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002355 * @return Returns true if the activity successfully finished, or false if it is still running.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 */
2357 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2358 // Refuse possible leaked file descriptors
2359 if (resultData != null && resultData.hasFileDescriptors() == true) {
2360 throw new IllegalArgumentException("File descriptors passed in Intent");
2361 }
2362
2363 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002364 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002366 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 if (next != null) {
2368 // ask watcher if this is allowed
2369 boolean resumeOK = true;
2370 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002371 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002373 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002374 }
2375
2376 if (!resumeOK) {
2377 return false;
2378 }
2379 }
2380 }
2381 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002382 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002383 resultData, "app-request");
2384 Binder.restoreCallingIdentity(origId);
2385 return res;
2386 }
2387 }
2388
Dianne Hackborn860755f2010-06-03 18:47:52 -07002389 public final void finishHeavyWeightApp() {
2390 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2391 != PackageManager.PERMISSION_GRANTED) {
2392 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2393 + Binder.getCallingPid()
2394 + ", uid=" + Binder.getCallingUid()
2395 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2396 Slog.w(TAG, msg);
2397 throw new SecurityException(msg);
2398 }
2399
2400 synchronized(this) {
2401 if (mHeavyWeightProcess == null) {
2402 return;
2403 }
2404
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002405 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002406 mHeavyWeightProcess.activities);
2407 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002408 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002409 if (!r.finishing) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002410 int index = mMainStack.indexOfTokenLocked(r);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002411 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002412 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002413 null, "finish-heavy");
2414 }
2415 }
2416 }
2417
2418 mHeavyWeightProcess = null;
2419 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2420 }
2421 }
2422
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002423 public void crashApplication(int uid, int initialPid, String packageName,
2424 String message) {
2425 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2426 != PackageManager.PERMISSION_GRANTED) {
2427 String msg = "Permission Denial: crashApplication() from pid="
2428 + Binder.getCallingPid()
2429 + ", uid=" + Binder.getCallingUid()
2430 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2431 Slog.w(TAG, msg);
2432 throw new SecurityException(msg);
2433 }
2434
2435 synchronized(this) {
2436 ProcessRecord proc = null;
2437
2438 // Figure out which process to kill. We don't trust that initialPid
2439 // still has any relation to current pids, so must scan through the
2440 // list.
2441 synchronized (mPidsSelfLocked) {
2442 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2443 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2444 if (p.info.uid != uid) {
2445 continue;
2446 }
2447 if (p.pid == initialPid) {
2448 proc = p;
2449 break;
2450 }
2451 for (String str : p.pkgList) {
2452 if (str.equals(packageName)) {
2453 proc = p;
2454 }
2455 }
2456 }
2457 }
2458
2459 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002460 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002461 + " initialPid=" + initialPid
2462 + " packageName=" + packageName);
2463 return;
2464 }
2465
2466 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002467 if (proc.pid == Process.myPid()) {
2468 Log.w(TAG, "crashApplication: trying to crash self!");
2469 return;
2470 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002471 long ident = Binder.clearCallingIdentity();
2472 try {
2473 proc.thread.scheduleCrash(message);
2474 } catch (RemoteException e) {
2475 }
2476 Binder.restoreCallingIdentity(ident);
2477 }
2478 }
2479 }
2480
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481 public final void finishSubActivity(IBinder token, String resultWho,
2482 int requestCode) {
2483 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002484 ActivityRecord self = mMainStack.isInStackLocked(token);
2485 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002486 return;
2487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002488
2489 final long origId = Binder.clearCallingIdentity();
2490
2491 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002492 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2493 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 if (r.resultTo == self && r.requestCode == requestCode) {
2495 if ((r.resultWho == null && resultWho == null) ||
2496 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002497 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 Activity.RESULT_CANCELED, null, "request-sub");
2499 }
2500 }
2501 }
2502
2503 Binder.restoreCallingIdentity(origId);
2504 }
2505 }
2506
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002507 public boolean willActivityBeVisible(IBinder token) {
2508 synchronized(this) {
2509 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002510 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2511 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002512 if (r == token) {
2513 return true;
2514 }
2515 if (r.fullscreen && !r.finishing) {
2516 return false;
2517 }
2518 }
2519 return true;
2520 }
2521 }
2522
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002523 public void overridePendingTransition(IBinder token, String packageName,
2524 int enterAnim, int exitAnim) {
2525 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002526 ActivityRecord self = mMainStack.isInStackLocked(token);
2527 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002528 return;
2529 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002530
2531 final long origId = Binder.clearCallingIdentity();
2532
2533 if (self.state == ActivityState.RESUMED
2534 || self.state == ActivityState.PAUSING) {
2535 mWindowManager.overridePendingAppTransition(packageName,
2536 enterAnim, exitAnim);
2537 }
2538
2539 Binder.restoreCallingIdentity(origId);
2540 }
2541 }
2542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002543 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002544 * Main function for removing an existing process from the activity manager
2545 * as a result of that process going away. Clears out all connections
2546 * to the process.
2547 */
2548 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002549 boolean restarting, boolean allowRestart) {
2550 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002551 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002552 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 }
2554
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002555 if (mProfileProc == app) {
2556 clearProfilerLocked();
2557 }
2558
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002559 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002560 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2561 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2562 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002564 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2565 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002566 }
2567
2568 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002569 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570
2571 boolean atTop = true;
2572 boolean hasVisibleActivities = false;
2573
2574 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002575 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002576 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 TAG, "Removing app " + app + " from history with " + i + " entries");
2578 while (i > 0) {
2579 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002580 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002581 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002582 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2583 if (r.app == app) {
2584 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002585 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002586 TAG, "Removing this entry! frozen=" + r.haveState
2587 + " finishing=" + r.finishing);
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002588 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002589 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002590 r.takeFromHistory();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002591 mWindowManager.removeAppToken(r);
2592 if (VALIDATE_TOKENS) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002593 mWindowManager.validateAppTokens(mMainStack.mHistory);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002594 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002595 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002596
2597 } else {
2598 // We have the current state for this activity, so
2599 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002600 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 TAG, "Keeping entry, setting app to null");
2602 if (r.visible) {
2603 hasVisibleActivities = true;
2604 }
2605 r.app = null;
2606 r.nowVisible = false;
2607 if (!r.haveState) {
2608 r.icicle = null;
2609 }
2610 }
2611
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002612 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 }
2614 atTop = false;
2615 }
2616
2617 app.activities.clear();
2618
2619 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002620 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 + " running instrumentation " + app.instrumentationClass);
2622 Bundle info = new Bundle();
2623 info.putString("shortMsg", "Process crashed.");
2624 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2625 }
2626
2627 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002628 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002629 // If there was nothing to resume, and we are not already
2630 // restarting this process, but there is a visible activity that
2631 // is hosted by the process... then make sure all visible
2632 // activities are running, taking care of restarting this
2633 // process.
2634 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002635 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 }
2637 }
2638 }
2639 }
2640
2641 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2642 IBinder threadBinder = thread.asBinder();
2643
2644 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002645 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2646 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2648 return i;
2649 }
2650 }
2651 return -1;
2652 }
2653
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002654 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002655 IApplicationThread thread) {
2656 if (thread == null) {
2657 return null;
2658 }
2659
2660 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002661 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002662 }
2663
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002664 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002665 IApplicationThread thread) {
2666
2667 mProcDeaths[0]++;
2668
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002669 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2670 synchronized (stats) {
2671 stats.noteProcessDiedLocked(app.info.uid, pid);
2672 }
2673
Magnus Edlund7bb25812010-02-24 15:45:06 +01002674 // Clean up already done if the process has been re-started.
2675 if (app.pid == pid && app.thread != null &&
2676 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002677 if (!app.killedBackground) {
2678 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2679 + ") has died.");
2680 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002681 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002682 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002683 TAG, "Dying app: " + app + ", pid: " + pid
2684 + ", thread: " + thread.asBinder());
2685 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002686 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002687
2688 if (doLowMem) {
2689 // If there are no longer any background processes running,
2690 // and the app that died was not running instrumentation,
2691 // then tell everyone we are now low on memory.
2692 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002693 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2694 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002695 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002696 haveBg = true;
2697 break;
2698 }
2699 }
2700
2701 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002702 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002703 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002704 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2705 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002706 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002707 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2708 // The low memory report is overriding any current
2709 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002710 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002711 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002712 rec.lastRequestedGc = 0;
2713 } else {
2714 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002716 rec.reportLowMemory = true;
2717 rec.lastLowMemory = now;
2718 mProcessesToGc.remove(rec);
2719 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 }
2721 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002722 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723 }
2724 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002725 } else if (app.pid != pid) {
2726 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002727 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002728 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002729 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002730 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002731 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732 + thread.asBinder());
2733 }
2734 }
2735
Dan Egnor42471dd2010-01-07 17:25:22 -08002736 /**
2737 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002738 * @param clearTraces causes the dump file to be erased prior to the new
2739 * traces being written, if true; when false, the new traces will be
2740 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002741 * @param firstPids of dalvik VM processes to dump stack traces for first
2742 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002743 * @return file containing stack traces, or null if no dump file is configured
2744 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002745 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2746 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002747 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2748 if (tracesPath == null || tracesPath.length() == 0) {
2749 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002750 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002751
2752 File tracesFile = new File(tracesPath);
2753 try {
2754 File tracesDir = tracesFile.getParentFile();
2755 if (!tracesDir.exists()) tracesFile.mkdirs();
2756 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2757
Christopher Tate6ee412d2010-05-28 12:01:56 -07002758 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002759 tracesFile.createNewFile();
2760 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2761 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002762 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002763 return null;
2764 }
2765
2766 // Use a FileObserver to detect when traces finish writing.
2767 // The order of traces is considered important to maintain for legibility.
2768 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2769 public synchronized void onEvent(int event, String path) { notify(); }
2770 };
2771
2772 try {
2773 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002774
2775 // First collect all of the stacks of the most important pids.
2776 try {
2777 int num = firstPids.size();
2778 for (int i = 0; i < num; i++) {
2779 synchronized (observer) {
2780 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2781 observer.wait(200); // Wait for write-close, give up after 200msec
2782 }
2783 }
2784 } catch (InterruptedException e) {
2785 Log.wtf(TAG, e);
2786 }
2787
2788 // Next measure CPU usage.
2789 if (processStats != null) {
2790 processStats.init();
2791 System.gc();
2792 processStats.update();
2793 try {
2794 synchronized (processStats) {
2795 processStats.wait(500); // measure over 1/2 second.
2796 }
2797 } catch (InterruptedException e) {
2798 }
2799 processStats.update();
2800
2801 // We'll take the stack crawls of just the top apps using CPU.
2802 final int N = processStats.countWorkingStats();
2803 int numProcs = 0;
2804 for (int i=0; i<N && numProcs<5; i++) {
2805 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2806 if (lastPids.indexOfKey(stats.pid) >= 0) {
2807 numProcs++;
2808 try {
2809 synchronized (observer) {
2810 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2811 observer.wait(200); // Wait for write-close, give up after 200msec
2812 }
2813 } catch (InterruptedException e) {
2814 Log.wtf(TAG, e);
2815 }
2816
2817 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002818 }
2819 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002820
2821 return tracesFile;
2822
Dan Egnor42471dd2010-01-07 17:25:22 -08002823 } finally {
2824 observer.stopWatching();
2825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 }
2827
Jeff Brown4d94a762010-09-23 11:33:28 -07002828 private final class AppNotResponding implements Runnable {
2829 private final ProcessRecord mApp;
2830 private final String mAnnotation;
2831
2832 public AppNotResponding(ProcessRecord app, String annotation) {
2833 mApp = app;
2834 mAnnotation = annotation;
2835 }
2836
2837 @Override
2838 public void run() {
2839 appNotResponding(mApp, null, null, mAnnotation);
2840 }
2841 }
2842
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002843 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2844 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002845 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2846 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2847
Dianne Hackborn287952c2010-09-22 22:34:31 -07002848 if (mController != null) {
2849 try {
2850 // 0 == continue, -1 = kill process immediately
2851 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2852 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2853 } catch (RemoteException e) {
2854 mController = null;
2855 }
2856 }
2857
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002858 long anrTime = SystemClock.uptimeMillis();
2859 if (MONITOR_CPU_USAGE) {
2860 updateCpuStatsNow();
2861 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002862
2863 synchronized (this) {
2864 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
2865 if (mShuttingDown) {
2866 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
2867 return;
2868 } else if (app.notResponding) {
2869 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
2870 return;
2871 } else if (app.crashing) {
2872 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
2873 return;
2874 }
2875
2876 // In case we come through here for the same app before completing
2877 // this one, mark as anring now so we will bail out.
2878 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08002879
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002880 // Log the ANR to the event log.
2881 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
2882 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08002883
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002884 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002885 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002886
2887 int parentPid = app.pid;
2888 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002889 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002890
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002891 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08002892
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002893 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
2894 ProcessRecord r = mLruProcesses.get(i);
2895 if (r != null && r.thread != null) {
2896 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002897 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
2898 if (r.persistent) {
2899 firstPids.add(pid);
2900 } else {
2901 lastPids.put(pid, Boolean.TRUE);
2902 }
2903 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 }
2906 }
2907
Dan Egnor42471dd2010-01-07 17:25:22 -08002908 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002909 StringBuilder info = mStringBuilder;
2910 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08002911 info.append("ANR in ").append(app.processName);
2912 if (activity != null && activity.shortComponentName != null) {
2913 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07002914 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08002915 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002917 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002918 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002919 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08002920 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922
Dianne Hackborn287952c2010-09-22 22:34:31 -07002923 final ProcessStats processStats = new ProcessStats(true);
2924
2925 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
2926
Dan Egnor42471dd2010-01-07 17:25:22 -08002927 String cpuInfo = null;
2928 if (MONITOR_CPU_USAGE) {
2929 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002930 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002931 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002932 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002933 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08002934 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 }
2936
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002937 info.append(processStats.printCurrentState(anrTime));
2938
Joe Onorato8a9b2202010-02-26 18:56:32 -08002939 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08002940 if (tracesFile == null) {
2941 // There is no trace file, so dump (only) the alleged culprit's threads to the log
2942 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
2943 }
2944
2945 addErrorToDropBox("anr", app, activity, parent, annotation, cpuInfo, tracesFile, null);
2946
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002947 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08002949 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
2950 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002951 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002952 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2953 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002954 }
2955 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002956 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 }
2958 }
2959
Dan Egnor42471dd2010-01-07 17:25:22 -08002960 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
2961 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
2962 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002963
2964 synchronized (this) {
2965 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002966 Slog.w(TAG, "Killing " + app + ": background ANR");
2967 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
2968 app.processName, app.setAdj, "background ANR");
2969 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07002970 return;
2971 }
2972
2973 // Set the app's notResponding state, and look up the errorReportReceiver
2974 makeAppNotRespondingLocked(app,
2975 activity != null ? activity.shortComponentName : null,
2976 annotation != null ? "ANR " + annotation : "ANR",
2977 info.toString());
2978
2979 // Bring up the infamous App Not Responding dialog
2980 Message msg = Message.obtain();
2981 HashMap map = new HashMap();
2982 msg.what = SHOW_NOT_RESPONDING_MSG;
2983 msg.obj = map;
2984 map.put("app", app);
2985 if (activity != null) {
2986 map.put("activity", activity);
2987 }
2988
2989 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08002990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002991 }
2992
Dianne Hackborn0dad3642010-09-09 21:25:35 -07002993 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
2994 if (!mLaunchWarningShown) {
2995 mLaunchWarningShown = true;
2996 mHandler.post(new Runnable() {
2997 @Override
2998 public void run() {
2999 synchronized (ActivityManagerService.this) {
3000 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3001 d.show();
3002 mHandler.postDelayed(new Runnable() {
3003 @Override
3004 public void run() {
3005 synchronized (ActivityManagerService.this) {
3006 d.dismiss();
3007 mLaunchWarningShown = false;
3008 }
3009 }
3010 }, 4000);
3011 }
3012 }
3013 });
3014 }
3015 }
3016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 public boolean clearApplicationUserData(final String packageName,
3018 final IPackageDataObserver observer) {
3019 int uid = Binder.getCallingUid();
3020 int pid = Binder.getCallingPid();
3021 long callingId = Binder.clearCallingIdentity();
3022 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003023 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003024 int pkgUid = -1;
3025 synchronized(this) {
3026 try {
3027 pkgUid = pm.getPackageUid(packageName);
3028 } catch (RemoteException e) {
3029 }
3030 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003031 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 return false;
3033 }
3034 if (uid == pkgUid || checkComponentPermission(
3035 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003036 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003037 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003038 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003039 } else {
3040 throw new SecurityException(pid+" does not have permission:"+
3041 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3042 "for process:"+packageName);
3043 }
3044 }
3045
3046 try {
3047 //clear application user data
3048 pm.clearApplicationUserData(packageName, observer);
3049 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3050 Uri.fromParts("package", packageName, null));
3051 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003052 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3053 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 } catch (RemoteException e) {
3055 }
3056 } finally {
3057 Binder.restoreCallingIdentity(callingId);
3058 }
3059 return true;
3060 }
3061
Dianne Hackborn03abb812010-01-04 18:43:19 -08003062 public void killBackgroundProcesses(final String packageName) {
3063 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3064 != PackageManager.PERMISSION_GRANTED &&
3065 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3066 != PackageManager.PERMISSION_GRANTED) {
3067 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003068 + Binder.getCallingPid()
3069 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003070 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003071 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003072 throw new SecurityException(msg);
3073 }
3074
3075 long callingId = Binder.clearCallingIdentity();
3076 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003077 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003078 int pkgUid = -1;
3079 synchronized(this) {
3080 try {
3081 pkgUid = pm.getPackageUid(packageName);
3082 } catch (RemoteException e) {
3083 }
3084 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003085 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003086 return;
3087 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003088 killPackageProcessesLocked(packageName, pkgUid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003089 ProcessList.SECONDARY_SERVER_ADJ, false, true, true, false);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003090 }
3091 } finally {
3092 Binder.restoreCallingIdentity(callingId);
3093 }
3094 }
3095
3096 public void forceStopPackage(final String packageName) {
3097 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3098 != PackageManager.PERMISSION_GRANTED) {
3099 String msg = "Permission Denial: forceStopPackage() from pid="
3100 + Binder.getCallingPid()
3101 + ", uid=" + Binder.getCallingUid()
3102 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003103 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003104 throw new SecurityException(msg);
3105 }
3106
3107 long callingId = Binder.clearCallingIdentity();
3108 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003109 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003110 int pkgUid = -1;
3111 synchronized(this) {
3112 try {
3113 pkgUid = pm.getPackageUid(packageName);
3114 } catch (RemoteException e) {
3115 }
3116 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003117 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003118 return;
3119 }
3120 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003121 try {
3122 pm.setPackageStoppedState(packageName, true);
3123 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003124 } catch (IllegalArgumentException e) {
3125 Slog.w(TAG, "Failed trying to unstop package "
3126 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 }
3129 } finally {
3130 Binder.restoreCallingIdentity(callingId);
3131 }
3132 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003133
3134 /*
3135 * The pkg name and uid have to be specified.
3136 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3137 */
3138 public void killApplicationWithUid(String pkg, int uid) {
3139 if (pkg == null) {
3140 return;
3141 }
3142 // Make sure the uid is valid.
3143 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003144 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003145 return;
3146 }
3147 int callerUid = Binder.getCallingUid();
3148 // Only the system server can kill an application
3149 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003150 // Post an aysnc message to kill the application
3151 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3152 msg.arg1 = uid;
3153 msg.arg2 = 0;
3154 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003155 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003156 } else {
3157 throw new SecurityException(callerUid + " cannot kill pkg: " +
3158 pkg);
3159 }
3160 }
3161
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003162 public void closeSystemDialogs(String reason) {
3163 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003164 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003165 if (reason != null) {
3166 intent.putExtra("reason", reason);
3167 }
3168
3169 final int uid = Binder.getCallingUid();
3170 final long origId = Binder.clearCallingIdentity();
3171 synchronized (this) {
3172 int i = mWatchers.beginBroadcast();
3173 while (i > 0) {
3174 i--;
3175 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3176 if (w != null) {
3177 try {
3178 w.closingSystemDialogs(reason);
3179 } catch (RemoteException e) {
3180 }
3181 }
3182 }
3183 mWatchers.finishBroadcast();
3184
Dianne Hackbornffa42482009-09-23 22:20:11 -07003185 mWindowManager.closeSystemDialogs(reason);
3186
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003187 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3188 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003189 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003190 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003191 Activity.RESULT_CANCELED, null, "close-sys");
3192 }
3193 }
3194
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003195 broadcastIntentLocked(null, null, intent, null,
3196 null, 0, null, null, null, false, false, -1, uid);
3197 }
3198 Binder.restoreCallingIdentity(origId);
3199 }
3200
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003201 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003202 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003203 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3204 for (int i=pids.length-1; i>=0; i--) {
3205 infos[i] = new Debug.MemoryInfo();
3206 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003207 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003208 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003209 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003210
Dianne Hackbornb437e092011-08-05 17:50:29 -07003211 public long[] getProcessPss(int[] pids) throws RemoteException {
3212 long[] pss = new long[pids.length];
3213 for (int i=pids.length-1; i>=0; i--) {
3214 pss[i] = Debug.getPss(pids[i]);
3215 }
3216 return pss;
3217 }
3218
Christopher Tate5e1ab332009-09-01 20:32:49 -07003219 public void killApplicationProcess(String processName, int uid) {
3220 if (processName == null) {
3221 return;
3222 }
3223
3224 int callerUid = Binder.getCallingUid();
3225 // Only the system server can kill an application
3226 if (callerUid == Process.SYSTEM_UID) {
3227 synchronized (this) {
3228 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003229 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003230 try {
3231 app.thread.scheduleSuicide();
3232 } catch (RemoteException e) {
3233 // If the other end already died, then our work here is done.
3234 }
3235 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003236 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003237 + processName + " / " + uid);
3238 }
3239 }
3240 } else {
3241 throw new SecurityException(callerUid + " cannot kill app process: " +
3242 processName);
3243 }
3244 }
3245
Dianne Hackborn03abb812010-01-04 18:43:19 -08003246 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003247 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003248 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3249 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003250 if (!mProcessesReady) {
3251 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3252 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003253 intent.putExtra(Intent.EXTRA_UID, uid);
3254 broadcastIntentLocked(null, null, intent,
3255 null, null, 0, null, null, null,
3256 false, false, MY_PID, Process.SYSTEM_UID);
3257 }
3258
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003259 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003260 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
3261 boolean evenPersistent) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003262 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003263
Dianne Hackborn03abb812010-01-04 18:43:19 -08003264 // Remove all processes this package may have touched: all with the
3265 // same UID (except for the system or root user), and all whose name
3266 // matches the package name.
3267 final String procNamePrefix = packageName + ":";
3268 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3269 final int NA = apps.size();
3270 for (int ia=0; ia<NA; ia++) {
3271 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003272 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003273 // we don't kill persistent processes
3274 continue;
3275 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003276 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003277 if (doit) {
3278 procs.add(app);
3279 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003280 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3281 || app.processName.equals(packageName)
3282 || app.processName.startsWith(procNamePrefix)) {
3283 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003284 if (!doit) {
3285 return true;
3286 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003287 app.removed = true;
3288 procs.add(app);
3289 }
3290 }
3291 }
3292 }
3293
3294 int N = procs.size();
3295 for (int i=0; i<N; i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003296 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003297 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003298 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003299 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003300
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003301 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003302 boolean callerWillRestart, boolean purgeCache, boolean doit,
3303 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003304 int i;
3305 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003307 if (uid < 0) {
3308 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003309 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 } catch (RemoteException e) {
3311 }
3312 }
3313
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003314 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003315 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003316
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003317 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3318 while (badApps.hasNext()) {
3319 SparseArray<Long> ba = badApps.next();
3320 if (ba.get(uid) != null) {
3321 badApps.remove();
3322 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003323 }
3324 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003325
3326 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Christopher Tate3dacd842011-08-19 14:56:15 -07003327 callerWillRestart, false, doit, evenPersistent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003329 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3330 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Christopher Tate064d8422011-07-26 15:38:07 -07003331 if (r.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003332 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003333 if (!doit) {
3334 return true;
3335 }
3336 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003337 Slog.i(TAG, " Force finishing activity " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 if (r.app != null) {
3339 r.app.removed = true;
3340 }
3341 r.app = null;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003342 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "uninstall");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 }
3344 }
3345
3346 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3347 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003348 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003349 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003350 if (!doit) {
3351 return true;
3352 }
3353 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003354 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003355 if (service.app != null) {
3356 service.app.removed = true;
3357 }
3358 service.app = null;
3359 services.add(service);
3360 }
3361 }
3362
3363 N = services.size();
3364 for (i=0; i<N; i++) {
3365 bringDownServiceLocked(services.get(i), true);
3366 }
3367
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003368 if (doit) {
3369 if (purgeCache) {
3370 AttributeCache ac = AttributeCache.instance();
3371 if (ac != null) {
3372 ac.removePackage(name);
3373 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003374 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003375 mMainStack.resumeTopActivityLocked(null);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003376 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003377
3378 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 }
3380
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003381 private final boolean removeProcessLocked(ProcessRecord app,
3382 boolean callerWillRestart, boolean allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 final String name = app.processName;
3384 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003385 if (DEBUG_PROCESSES) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003386 TAG, "Force removing process " + app + " (" + name
3387 + "/" + uid + ")");
3388
3389 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003390 if (mHeavyWeightProcess == app) {
3391 mHeavyWeightProcess = null;
3392 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 boolean needRestart = false;
3395 if (app.pid > 0 && app.pid != MY_PID) {
3396 int pid = app.pid;
3397 synchronized (mPidsSelfLocked) {
3398 mPidsSelfLocked.remove(pid);
3399 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3400 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003401 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003402 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 Process.killProcess(pid);
3404
3405 if (app.persistent) {
3406 if (!callerWillRestart) {
3407 addAppLocked(app.info);
3408 } else {
3409 needRestart = true;
3410 }
3411 }
3412 } else {
3413 mRemovedProcesses.add(app);
3414 }
3415
3416 return needRestart;
3417 }
3418
3419 private final void processStartTimedOutLocked(ProcessRecord app) {
3420 final int pid = app.pid;
3421 boolean gone = false;
3422 synchronized (mPidsSelfLocked) {
3423 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3424 if (knownApp != null && knownApp.thread == null) {
3425 mPidsSelfLocked.remove(pid);
3426 gone = true;
3427 }
3428 }
3429
3430 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003431 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003432 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003433 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003435 if (mHeavyWeightProcess == app) {
3436 mHeavyWeightProcess = null;
3437 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3438 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003439 // Take care of any launching providers waiting for this process.
3440 checkAppInLaunchingProvidersLocked(app, true);
3441 // Take care of any services that are waiting for the process.
3442 for (int i=0; i<mPendingServices.size(); i++) {
3443 ServiceRecord sr = mPendingServices.get(i);
3444 if (app.info.uid == sr.appInfo.uid
3445 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003446 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003447 mPendingServices.remove(i);
3448 i--;
3449 bringDownServiceLocked(sr, true);
3450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003451 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003452 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3453 app.processName, app.setAdj, "start timeout");
3454 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003455 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003456 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003457 try {
3458 IBackupManager bm = IBackupManager.Stub.asInterface(
3459 ServiceManager.getService(Context.BACKUP_SERVICE));
3460 bm.agentDisconnected(app.info.packageName);
3461 } catch (RemoteException e) {
3462 // Can't happen; the backup manager is local
3463 }
3464 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003465 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003466 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003467 mPendingBroadcast.state = BroadcastRecord.IDLE;
3468 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003469 mPendingBroadcast = null;
3470 scheduleBroadcastsLocked();
3471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003472 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003473 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 }
3475 }
3476
3477 private final boolean attachApplicationLocked(IApplicationThread thread,
3478 int pid) {
3479
3480 // Find the application record that is being attached... either via
3481 // the pid if we are running in multiple processes, or just pull the
3482 // next app record if we are emulating process with anonymous threads.
3483 ProcessRecord app;
3484 if (pid != MY_PID && pid >= 0) {
3485 synchronized (mPidsSelfLocked) {
3486 app = mPidsSelfLocked.get(pid);
3487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488 } else {
3489 app = null;
3490 }
3491
3492 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003493 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003494 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003495 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003497 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 } else {
3499 try {
3500 thread.scheduleExit();
3501 } catch (Exception e) {
3502 // Ignore exceptions.
3503 }
3504 }
3505 return false;
3506 }
3507
3508 // If this application record is still attached to a previous
3509 // process, clean it up now.
3510 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003511 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003512 }
3513
3514 // Tell the process all about itself.
3515
Joe Onorato8a9b2202010-02-26 18:56:32 -08003516 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 TAG, "Binding process pid " + pid + " to record " + app);
3518
3519 String processName = app.processName;
3520 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003521 AppDeathRecipient adr = new AppDeathRecipient(
3522 app, pid, thread);
3523 thread.asBinder().linkToDeath(adr, 0);
3524 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003525 } catch (RemoteException e) {
3526 app.resetPackageList();
3527 startProcessLocked(app, "link fail", processName);
3528 return false;
3529 }
3530
Doug Zongker2bec3d42009-12-04 12:52:44 -08003531 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532
3533 app.thread = thread;
3534 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003535 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3536 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 app.forcingToForeground = null;
3538 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003539 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003540 app.debugging = false;
3541
3542 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3543
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003544 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003545 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003546
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003547 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003548 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003549 }
3550
Joe Onorato8a9b2202010-02-26 18:56:32 -08003551 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003552 TAG, "New app record " + app
3553 + " thread=" + thread.asBinder() + " pid=" + pid);
3554 try {
3555 int testMode = IApplicationThread.DEBUG_OFF;
3556 if (mDebugApp != null && mDebugApp.equals(processName)) {
3557 testMode = mWaitForDebugger
3558 ? IApplicationThread.DEBUG_WAIT
3559 : IApplicationThread.DEBUG_ON;
3560 app.debugging = true;
3561 if (mDebugTransient) {
3562 mDebugApp = mOrigDebugApp;
3563 mWaitForDebugger = mOrigWaitForDebugger;
3564 }
3565 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003566 String profileFile = app.instrumentationProfileFile;
3567 ParcelFileDescriptor profileFd = null;
3568 boolean profileAutoStop = false;
3569 if (mProfileApp != null && mProfileApp.equals(processName)) {
3570 mProfileProc = app;
3571 profileFile = mProfileFile;
3572 profileFd = mProfileFd;
3573 profileAutoStop = mAutoStopProfiler;
3574 }
3575
Christopher Tate181fafa2009-05-14 11:12:14 -07003576 // If the app is being launched for restore or full backup, set it up specially
3577 boolean isRestrictedBackupMode = false;
3578 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3579 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003580 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003581 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3582 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003583
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003584 ensurePackageDexOpt(app.instrumentationInfo != null
3585 ? app.instrumentationInfo.packageName
3586 : app.info.packageName);
3587 if (app.instrumentationClass != null) {
3588 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003589 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003590 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003591 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003592 ApplicationInfo appInfo = app.instrumentationInfo != null
3593 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003594 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003595 if (profileFd != null) {
3596 profileFd = profileFd.dup();
3597 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003598 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003599 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003600 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003601 isRestrictedBackupMode || !normalMode,
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003602 mConfiguration, app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003603 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003604 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003605 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003606 } catch (Exception e) {
3607 // todo: Yikes! What should we do? For now we will try to
3608 // start another process, but that could easily get us in
3609 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003610 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003611
3612 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003613 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003614 startProcessLocked(app, "bind fail", processName);
3615 return false;
3616 }
3617
3618 // Remove this record from the list of starting applications.
3619 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003620 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3621 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003622 mProcessesOnHold.remove(app);
3623
3624 boolean badApp = false;
3625 boolean didSomething = false;
3626
3627 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003628 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003629 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003630 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3631 && processName.equals(hr.processName)) {
3632 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003633 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003634 didSomething = true;
3635 }
3636 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003637 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 + hr.intent.getComponent().flattenToShortString(), e);
3639 badApp = true;
3640 }
3641 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003642 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003643 }
3644 }
3645
3646 // Find any services that should be running in this process...
3647 if (!badApp && mPendingServices.size() > 0) {
3648 ServiceRecord sr = null;
3649 try {
3650 for (int i=0; i<mPendingServices.size(); i++) {
3651 sr = mPendingServices.get(i);
3652 if (app.info.uid != sr.appInfo.uid
3653 || !processName.equals(sr.processName)) {
3654 continue;
3655 }
3656
3657 mPendingServices.remove(i);
3658 i--;
3659 realStartServiceLocked(sr, app);
3660 didSomething = true;
3661 }
3662 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003663 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 + sr.shortName, e);
3665 badApp = true;
3666 }
3667 }
3668
3669 // Check if the next broadcast receiver is in this process...
3670 BroadcastRecord br = mPendingBroadcast;
3671 if (!badApp && br != null && br.curApp == app) {
3672 try {
3673 mPendingBroadcast = null;
3674 processCurBroadcastLocked(br, app);
3675 didSomething = true;
3676 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003677 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003678 + br.curComponent.flattenToShortString(), e);
3679 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003680 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003681 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3682 br.resultExtras, br.resultAbort, true);
3683 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003684 // We need to reset the state if we fails to start the receiver.
3685 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003686 }
3687 }
3688
Christopher Tate181fafa2009-05-14 11:12:14 -07003689 // Check whether the next backup agent is in this process...
3690 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003691 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003692 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003693 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003694 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3695 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3696 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003697 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003698 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003699 e.printStackTrace();
3700 }
3701 }
3702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003703 if (badApp) {
3704 // todo: Also need to kill application to deal with all
3705 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003706 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003707 return false;
3708 }
3709
3710 if (!didSomething) {
3711 updateOomAdjLocked();
3712 }
3713
3714 return true;
3715 }
3716
3717 public final void attachApplication(IApplicationThread thread) {
3718 synchronized (this) {
3719 int callingPid = Binder.getCallingPid();
3720 final long origId = Binder.clearCallingIdentity();
3721 attachApplicationLocked(thread, callingPid);
3722 Binder.restoreCallingIdentity(origId);
3723 }
3724 }
3725
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003726 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003728 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3729 if (stopProfiling) {
3730 synchronized (this) {
3731 if (mProfileProc == r.app) {
3732 if (mProfileFd != null) {
3733 try {
3734 mProfileFd.close();
3735 } catch (IOException e) {
3736 }
3737 clearProfilerLocked();
3738 }
3739 }
3740 }
3741 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003742 Binder.restoreCallingIdentity(origId);
3743 }
3744
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003746 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003747 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748 mWindowManager.enableScreenAfterBoot();
3749 }
3750
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003751 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003752 IntentFilter pkgFilter = new IntentFilter();
3753 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3754 pkgFilter.addDataScheme("package");
3755 mContext.registerReceiver(new BroadcastReceiver() {
3756 @Override
3757 public void onReceive(Context context, Intent intent) {
3758 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3759 if (pkgs != null) {
3760 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003761 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003762 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003763 setResultCode(Activity.RESULT_OK);
3764 return;
3765 }
3766 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003767 }
3768 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003769 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003770 }, pkgFilter);
3771
3772 synchronized (this) {
3773 // Ensure that any processes we had put on hold are now started
3774 // up.
3775 final int NP = mProcessesOnHold.size();
3776 if (NP > 0) {
3777 ArrayList<ProcessRecord> procs =
3778 new ArrayList<ProcessRecord>(mProcessesOnHold);
3779 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003780 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3781 + procs.get(ip));
3782 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003783 }
3784 }
3785
3786 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003787 // Start looking for apps that are abusing wake locks.
3788 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003789 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003790 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003791 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003792 broadcastIntentLocked(null, null,
3793 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3794 null, null, 0, null, null,
3795 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3796 false, false, MY_PID, Process.SYSTEM_UID);
3797 }
3798 }
3799 }
3800
3801 final void ensureBootCompleted() {
3802 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003803 boolean enableScreen;
3804 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003805 booting = mBooting;
3806 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003807 enableScreen = !mBooted;
3808 mBooted = true;
3809 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003810
3811 if (booting) {
3812 finishBooting();
3813 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003814
3815 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003816 enableScreenAfterBoot();
3817 }
3818 }
3819
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003820 public final void activityPaused(IBinder token) {
3821 final long origId = Binder.clearCallingIdentity();
3822 mMainStack.activityPaused(token, false);
3823 Binder.restoreCallingIdentity(origId);
3824 }
3825
3826 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3827 CharSequence description) {
3828 if (localLOGV) Slog.v(
3829 TAG, "Activity stopped: token=" + token);
3830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 // Refuse possible leaked file descriptors
3832 if (icicle != null && icicle.hasFileDescriptors()) {
3833 throw new IllegalArgumentException("File descriptors passed in Bundle");
3834 }
3835
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003836 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003837
3838 final long origId = Binder.clearCallingIdentity();
3839
3840 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003841 r = mMainStack.isInStackLocked(token);
3842 if (r != null) {
3843 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003844 }
3845 }
3846
3847 if (r != null) {
3848 sendPendingThumbnail(r, null, null, null, false);
3849 }
3850
3851 trimApplications();
3852
3853 Binder.restoreCallingIdentity(origId);
3854 }
3855
3856 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003857 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003858 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 }
3860
3861 public String getCallingPackage(IBinder token) {
3862 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003863 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003864 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003865 }
3866 }
3867
3868 public ComponentName getCallingActivity(IBinder token) {
3869 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003870 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003871 return r != null ? r.intent.getComponent() : null;
3872 }
3873 }
3874
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003875 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003876 ActivityRecord r = mMainStack.isInStackLocked(token);
3877 if (r == null) {
3878 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003880 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003881 }
3882
3883 public ComponentName getActivityClassForToken(IBinder token) {
3884 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003885 ActivityRecord r = mMainStack.isInStackLocked(token);
3886 if (r == null) {
3887 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003889 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003890 }
3891 }
3892
3893 public String getPackageForToken(IBinder token) {
3894 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003895 ActivityRecord r = mMainStack.isInStackLocked(token);
3896 if (r == null) {
3897 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003899 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003900 }
3901 }
3902
3903 public IIntentSender getIntentSender(int type,
3904 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003905 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003906 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003907 if (intents != null) {
3908 if (intents.length < 1) {
3909 throw new IllegalArgumentException("Intents array length must be >= 1");
3910 }
3911 for (int i=0; i<intents.length; i++) {
3912 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003913 if (intent != null) {
3914 if (intent.hasFileDescriptors()) {
3915 throw new IllegalArgumentException("File descriptors passed in Intent");
3916 }
3917 if (type == INTENT_SENDER_BROADCAST &&
3918 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3919 throw new IllegalArgumentException(
3920 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3921 }
3922 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003923 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003924 }
3925 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003926 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003927 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003928 }
3929 }
3930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 synchronized(this) {
3932 int callingUid = Binder.getCallingUid();
3933 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003934 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003935 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003936 .getPackageUid(packageName);
3937 if (uid != Binder.getCallingUid()) {
3938 String msg = "Permission Denial: getIntentSender() from pid="
3939 + Binder.getCallingPid()
3940 + ", uid=" + Binder.getCallingUid()
3941 + ", (need uid=" + uid + ")"
3942 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003943 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 throw new SecurityException(msg);
3945 }
3946 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003947
3948 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003949 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003950
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003951 } catch (RemoteException e) {
3952 throw new SecurityException(e);
3953 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003954 }
3955 }
3956
3957 IIntentSender getIntentSenderLocked(int type,
3958 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003959 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003960 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003961 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003962 activity = mMainStack.isInStackLocked(token);
3963 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003964 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003965 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003966 if (activity.finishing) {
3967 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003968 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003969 }
3970
3971 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3972 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3973 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3974 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3975 |PendingIntent.FLAG_UPDATE_CURRENT);
3976
3977 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3978 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003979 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003980 WeakReference<PendingIntentRecord> ref;
3981 ref = mIntentSenderRecords.get(key);
3982 PendingIntentRecord rec = ref != null ? ref.get() : null;
3983 if (rec != null) {
3984 if (!cancelCurrent) {
3985 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003986 if (rec.key.requestIntent != null) {
3987 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3988 }
3989 if (intents != null) {
3990 intents[intents.length-1] = rec.key.requestIntent;
3991 rec.key.allIntents = intents;
3992 rec.key.allResolvedTypes = resolvedTypes;
3993 } else {
3994 rec.key.allIntents = null;
3995 rec.key.allResolvedTypes = null;
3996 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003998 return rec;
3999 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004000 rec.canceled = true;
4001 mIntentSenderRecords.remove(key);
4002 }
4003 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004004 return rec;
4005 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004006 rec = new PendingIntentRecord(this, key, callingUid);
4007 mIntentSenderRecords.put(key, rec.ref);
4008 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4009 if (activity.pendingResults == null) {
4010 activity.pendingResults
4011 = new HashSet<WeakReference<PendingIntentRecord>>();
4012 }
4013 activity.pendingResults.add(rec.ref);
4014 }
4015 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004016 }
4017
4018 public void cancelIntentSender(IIntentSender sender) {
4019 if (!(sender instanceof PendingIntentRecord)) {
4020 return;
4021 }
4022 synchronized(this) {
4023 PendingIntentRecord rec = (PendingIntentRecord)sender;
4024 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004025 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004026 .getPackageUid(rec.key.packageName);
4027 if (uid != Binder.getCallingUid()) {
4028 String msg = "Permission Denial: cancelIntentSender() from pid="
4029 + Binder.getCallingPid()
4030 + ", uid=" + Binder.getCallingUid()
4031 + " is not allowed to cancel packges "
4032 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004033 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034 throw new SecurityException(msg);
4035 }
4036 } catch (RemoteException e) {
4037 throw new SecurityException(e);
4038 }
4039 cancelIntentSenderLocked(rec, true);
4040 }
4041 }
4042
4043 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4044 rec.canceled = true;
4045 mIntentSenderRecords.remove(rec.key);
4046 if (cleanActivity && rec.key.activity != null) {
4047 rec.key.activity.pendingResults.remove(rec.ref);
4048 }
4049 }
4050
4051 public String getPackageForIntentSender(IIntentSender pendingResult) {
4052 if (!(pendingResult instanceof PendingIntentRecord)) {
4053 return null;
4054 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004055 try {
4056 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4057 return res.key.packageName;
4058 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004059 }
4060 return null;
4061 }
4062
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004063 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4064 if (!(pendingResult instanceof PendingIntentRecord)) {
4065 return false;
4066 }
4067 try {
4068 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4069 if (res.key.allIntents == null) {
4070 return false;
4071 }
4072 for (int i=0; i<res.key.allIntents.length; i++) {
4073 Intent intent = res.key.allIntents[i];
4074 if (intent.getPackage() != null && intent.getComponent() != null) {
4075 return false;
4076 }
4077 }
4078 return true;
4079 } catch (ClassCastException e) {
4080 }
4081 return false;
4082 }
4083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004084 public void setProcessLimit(int max) {
4085 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4086 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004087 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004088 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004089 mProcessLimitOverride = max;
4090 }
4091 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092 }
4093
4094 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004095 synchronized (this) {
4096 return mProcessLimitOverride;
4097 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004098 }
4099
4100 void foregroundTokenDied(ForegroundToken token) {
4101 synchronized (ActivityManagerService.this) {
4102 synchronized (mPidsSelfLocked) {
4103 ForegroundToken cur
4104 = mForegroundProcesses.get(token.pid);
4105 if (cur != token) {
4106 return;
4107 }
4108 mForegroundProcesses.remove(token.pid);
4109 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4110 if (pr == null) {
4111 return;
4112 }
4113 pr.forcingToForeground = null;
4114 pr.foregroundServices = false;
4115 }
4116 updateOomAdjLocked();
4117 }
4118 }
4119
4120 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4121 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4122 "setProcessForeground()");
4123 synchronized(this) {
4124 boolean changed = false;
4125
4126 synchronized (mPidsSelfLocked) {
4127 ProcessRecord pr = mPidsSelfLocked.get(pid);
4128 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004129 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 return;
4131 }
4132 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4133 if (oldToken != null) {
4134 oldToken.token.unlinkToDeath(oldToken, 0);
4135 mForegroundProcesses.remove(pid);
4136 pr.forcingToForeground = null;
4137 changed = true;
4138 }
4139 if (isForeground && token != null) {
4140 ForegroundToken newToken = new ForegroundToken() {
4141 public void binderDied() {
4142 foregroundTokenDied(this);
4143 }
4144 };
4145 newToken.pid = pid;
4146 newToken.token = token;
4147 try {
4148 token.linkToDeath(newToken, 0);
4149 mForegroundProcesses.put(pid, newToken);
4150 pr.forcingToForeground = token;
4151 changed = true;
4152 } catch (RemoteException e) {
4153 // If the process died while doing this, we will later
4154 // do the cleanup with the process death link.
4155 }
4156 }
4157 }
4158
4159 if (changed) {
4160 updateOomAdjLocked();
4161 }
4162 }
4163 }
4164
4165 // =========================================================
4166 // PERMISSIONS
4167 // =========================================================
4168
4169 static class PermissionController extends IPermissionController.Stub {
4170 ActivityManagerService mActivityManagerService;
4171 PermissionController(ActivityManagerService activityManagerService) {
4172 mActivityManagerService = activityManagerService;
4173 }
4174
4175 public boolean checkPermission(String permission, int pid, int uid) {
4176 return mActivityManagerService.checkPermission(permission, pid,
4177 uid) == PackageManager.PERMISSION_GRANTED;
4178 }
4179 }
4180
4181 /**
4182 * This can be called with or without the global lock held.
4183 */
4184 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004185 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004186 // We might be performing an operation on behalf of an indirect binder
4187 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4188 // client identity accordingly before proceeding.
4189 Identity tlsIdentity = sCallerIdentity.get();
4190 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004191 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004192 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4193 uid = tlsIdentity.uid;
4194 pid = tlsIdentity.pid;
4195 }
4196
4197 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004198 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 return PackageManager.PERMISSION_GRANTED;
4200 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004201 // If there is a uid that owns whatever is being accessed, it has
4202 // blanket access to it regardless of the permissions it requires.
4203 if (owningUid >= 0 && uid == owningUid) {
4204 return PackageManager.PERMISSION_GRANTED;
4205 }
4206 // If the target is not exported, then nobody else can get to it.
4207 if (!exported) {
4208 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004209 return PackageManager.PERMISSION_DENIED;
4210 }
4211 if (permission == null) {
4212 return PackageManager.PERMISSION_GRANTED;
4213 }
4214 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004215 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 .checkUidPermission(permission, uid);
4217 } catch (RemoteException e) {
4218 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004219 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 }
4221 return PackageManager.PERMISSION_DENIED;
4222 }
4223
4224 /**
4225 * As the only public entry point for permissions checking, this method
4226 * can enforce the semantic that requesting a check on a null global
4227 * permission is automatically denied. (Internally a null permission
4228 * string is used when calling {@link #checkComponentPermission} in cases
4229 * when only uid-based security is needed.)
4230 *
4231 * This can be called with or without the global lock held.
4232 */
4233 public int checkPermission(String permission, int pid, int uid) {
4234 if (permission == null) {
4235 return PackageManager.PERMISSION_DENIED;
4236 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004237 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004238 }
4239
4240 /**
4241 * Binder IPC calls go through the public entry point.
4242 * This can be called with or without the global lock held.
4243 */
4244 int checkCallingPermission(String permission) {
4245 return checkPermission(permission,
4246 Binder.getCallingPid(),
4247 Binder.getCallingUid());
4248 }
4249
4250 /**
4251 * This can be called with or without the global lock held.
4252 */
4253 void enforceCallingPermission(String permission, String func) {
4254 if (checkCallingPermission(permission)
4255 == PackageManager.PERMISSION_GRANTED) {
4256 return;
4257 }
4258
4259 String msg = "Permission Denial: " + func + " from pid="
4260 + Binder.getCallingPid()
4261 + ", uid=" + Binder.getCallingUid()
4262 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004263 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004264 throw new SecurityException(msg);
4265 }
4266
4267 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004268 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4269 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4270 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4271 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4272 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004273 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004274 // Is the component private from the target uid?
4275 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4276
4277 // Acceptable if the there is no read permission needed from the
4278 // target or the target is holding the read permission.
4279 if (!readPerm) {
4280 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004281 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004282 == PackageManager.PERMISSION_GRANTED)) {
4283 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004284 }
4285 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004286
4287 // Acceptable if the there is no write permission needed from the
4288 // target or the target is holding the read permission.
4289 if (!writePerm) {
4290 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004292 == PackageManager.PERMISSION_GRANTED)) {
4293 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 }
4295 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004296
4297 // Acceptable if there is a path permission matching the URI that
4298 // the target holds the permission on.
4299 PathPermission[] pps = pi.pathPermissions;
4300 if (pps != null && (!readPerm || !writePerm)) {
4301 final String path = uri.getPath();
4302 int i = pps.length;
4303 while (i > 0 && (!readPerm || !writePerm)) {
4304 i--;
4305 PathPermission pp = pps[i];
4306 if (!readPerm) {
4307 final String pprperm = pp.getReadPermission();
4308 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4309 + pprperm + " for " + pp.getPath()
4310 + ": match=" + pp.match(path)
4311 + " check=" + pm.checkUidPermission(pprperm, uid));
4312 if (pprperm != null && pp.match(path) &&
4313 (pm.checkUidPermission(pprperm, uid)
4314 == PackageManager.PERMISSION_GRANTED)) {
4315 readPerm = true;
4316 }
4317 }
4318 if (!writePerm) {
4319 final String ppwperm = pp.getWritePermission();
4320 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4321 + ppwperm + " for " + pp.getPath()
4322 + ": match=" + pp.match(path)
4323 + " check=" + pm.checkUidPermission(ppwperm, uid));
4324 if (ppwperm != null && pp.match(path) &&
4325 (pm.checkUidPermission(ppwperm, uid)
4326 == PackageManager.PERMISSION_GRANTED)) {
4327 writePerm = true;
4328 }
4329 }
4330 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004332 } catch (RemoteException e) {
4333 return false;
4334 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004335
4336 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004337 }
4338
4339 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4340 int modeFlags) {
4341 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004342 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004343 return true;
4344 }
4345 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4346 if (perms == null) return false;
4347 UriPermission perm = perms.get(uri);
4348 if (perm == null) return false;
4349 return (modeFlags&perm.modeFlags) == modeFlags;
4350 }
4351
4352 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4353 // Another redirected-binder-call permissions check as in
4354 // {@link checkComponentPermission}.
4355 Identity tlsIdentity = sCallerIdentity.get();
4356 if (tlsIdentity != null) {
4357 uid = tlsIdentity.uid;
4358 pid = tlsIdentity.pid;
4359 }
4360
4361 // Our own process gets to do everything.
4362 if (pid == MY_PID) {
4363 return PackageManager.PERMISSION_GRANTED;
4364 }
4365 synchronized(this) {
4366 return checkUriPermissionLocked(uri, uid, modeFlags)
4367 ? PackageManager.PERMISSION_GRANTED
4368 : PackageManager.PERMISSION_DENIED;
4369 }
4370 }
4371
Dianne Hackborn39792d22010-08-19 18:01:52 -07004372 /**
4373 * Check if the targetPkg can be granted permission to access uri by
4374 * the callingUid using the given modeFlags. Throws a security exception
4375 * if callingUid is not allowed to do this. Returns the uid of the target
4376 * if the URI permission grant should be performed; returns -1 if it is not
4377 * needed (for example targetPkg already has permission to access the URI).
4378 */
4379 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4380 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004381 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4382 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4383 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004384 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 }
4386
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004387 if (targetPkg != null) {
4388 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4389 "Checking grant " + targetPkg + " permission to " + uri);
4390 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004391
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004392 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393
4394 // If this is not a content: uri, we can't do anything with it.
4395 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004396 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004397 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004398 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 }
4400
4401 String name = uri.getAuthority();
4402 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004403 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004404 if (cpr != null) {
4405 pi = cpr.info;
4406 } else {
4407 try {
4408 pi = pm.resolveContentProvider(name,
4409 PackageManager.GET_URI_PERMISSION_PATTERNS);
4410 } catch (RemoteException ex) {
4411 }
4412 }
4413 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004414 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004415 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004416 }
4417
4418 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004419 if (targetPkg != null) {
4420 try {
4421 targetUid = pm.getPackageUid(targetPkg);
4422 if (targetUid < 0) {
4423 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4424 "Can't grant URI permission no uid for: " + targetPkg);
4425 return -1;
4426 }
4427 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004428 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004429 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004430 } else {
4431 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004432 }
4433
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004434 if (targetUid >= 0) {
4435 // First... does the target actually need this permission?
4436 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4437 // No need to grant the target this permission.
4438 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4439 "Target " + targetPkg + " already has full permission to " + uri);
4440 return -1;
4441 }
4442 } else {
4443 // First... there is no target package, so can anyone access it?
4444 boolean allowed = pi.exported;
4445 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4446 if (pi.readPermission != null) {
4447 allowed = false;
4448 }
4449 }
4450 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4451 if (pi.writePermission != null) {
4452 allowed = false;
4453 }
4454 }
4455 if (allowed) {
4456 return -1;
4457 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 }
4459
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004460 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004461 if (!pi.grantUriPermissions) {
4462 throw new SecurityException("Provider " + pi.packageName
4463 + "/" + pi.name
4464 + " does not allow granting of Uri permissions (uri "
4465 + uri + ")");
4466 }
4467 if (pi.uriPermissionPatterns != null) {
4468 final int N = pi.uriPermissionPatterns.length;
4469 boolean allowed = false;
4470 for (int i=0; i<N; i++) {
4471 if (pi.uriPermissionPatterns[i] != null
4472 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4473 allowed = true;
4474 break;
4475 }
4476 }
4477 if (!allowed) {
4478 throw new SecurityException("Provider " + pi.packageName
4479 + "/" + pi.name
4480 + " does not allow granting of permission to path of Uri "
4481 + uri);
4482 }
4483 }
4484
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004485 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004486 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004487 if (callingUid != Process.myUid()) {
4488 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4489 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4490 throw new SecurityException("Uid " + callingUid
4491 + " does not have permission to uri " + uri);
4492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004493 }
4494 }
4495
Dianne Hackborn39792d22010-08-19 18:01:52 -07004496 return targetUid;
4497 }
4498
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004499 public int checkGrantUriPermission(int callingUid, String targetPkg,
4500 Uri uri, int modeFlags) {
4501 synchronized(this) {
4502 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4503 }
4504 }
4505
Dianne Hackborn39792d22010-08-19 18:01:52 -07004506 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4507 Uri uri, int modeFlags, UriPermissionOwner owner) {
4508 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4509 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4510 if (modeFlags == 0) {
4511 return;
4512 }
4513
4514 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004515 // to the uri, and the target doesn't. Let's now give this to
4516 // the target.
4517
Joe Onorato8a9b2202010-02-26 18:56:32 -08004518 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004519 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 HashMap<Uri, UriPermission> targetUris
4522 = mGrantedUriPermissions.get(targetUid);
4523 if (targetUris == null) {
4524 targetUris = new HashMap<Uri, UriPermission>();
4525 mGrantedUriPermissions.put(targetUid, targetUris);
4526 }
4527
4528 UriPermission perm = targetUris.get(uri);
4529 if (perm == null) {
4530 perm = new UriPermission(targetUid, uri);
4531 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004532 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004534 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004535 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004537 } else {
4538 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4539 perm.readOwners.add(owner);
4540 owner.addReadPermission(perm);
4541 }
4542 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4543 perm.writeOwners.add(owner);
4544 owner.addWritePermission(perm);
4545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004546 }
4547 }
4548
Dianne Hackborn39792d22010-08-19 18:01:52 -07004549 void grantUriPermissionLocked(int callingUid,
4550 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004551 if (targetPkg == null) {
4552 throw new NullPointerException("targetPkg");
4553 }
4554
Dianne Hackborn39792d22010-08-19 18:01:52 -07004555 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4556 if (targetUid < 0) {
4557 return;
4558 }
4559
4560 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4561 }
4562
4563 /**
4564 * Like checkGrantUriPermissionLocked, but takes an Intent.
4565 */
4566 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4567 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004568 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004569 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004570 + " from " + intent + "; flags=0x"
4571 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4572
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004573 if (targetPkg == null) {
4574 throw new NullPointerException("targetPkg");
4575 }
4576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004577 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004578 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004579 }
4580 Uri data = intent.getData();
4581 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004582 return -1;
4583 }
4584 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4585 intent.getFlags());
4586 }
4587
4588 /**
4589 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4590 */
4591 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4592 String targetPkg, Intent intent, UriPermissionOwner owner) {
4593 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4594 intent.getFlags(), owner);
4595 }
4596
4597 void grantUriPermissionFromIntentLocked(int callingUid,
4598 String targetPkg, Intent intent, UriPermissionOwner owner) {
4599 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4600 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601 return;
4602 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004603
4604 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 }
4606
4607 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4608 Uri uri, int modeFlags) {
4609 synchronized(this) {
4610 final ProcessRecord r = getRecordForAppLocked(caller);
4611 if (r == null) {
4612 throw new SecurityException("Unable to find app for caller "
4613 + caller
4614 + " when granting permission to uri " + uri);
4615 }
4616 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004617 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004618 }
4619 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004620 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004621 }
4622
4623 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4624 null);
4625 }
4626 }
4627
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004628 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4630 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4631 HashMap<Uri, UriPermission> perms
4632 = mGrantedUriPermissions.get(perm.uid);
4633 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004634 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004635 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004636 perms.remove(perm.uri);
4637 if (perms.size() == 0) {
4638 mGrantedUriPermissions.remove(perm.uid);
4639 }
4640 }
4641 }
4642 }
4643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004644 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4645 int modeFlags) {
4646 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4647 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4648 if (modeFlags == 0) {
4649 return;
4650 }
4651
Joe Onorato8a9b2202010-02-26 18:56:32 -08004652 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004653 "Revoking all granted permissions to " + uri);
4654
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004655 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656
4657 final String authority = uri.getAuthority();
4658 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004659 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 if (cpr != null) {
4661 pi = cpr.info;
4662 } else {
4663 try {
4664 pi = pm.resolveContentProvider(authority,
4665 PackageManager.GET_URI_PERMISSION_PATTERNS);
4666 } catch (RemoteException ex) {
4667 }
4668 }
4669 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004670 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004671 return;
4672 }
4673
4674 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004675 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004676 // Right now, if you are not the original owner of the permission,
4677 // you are not allowed to revoke it.
4678 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4679 throw new SecurityException("Uid " + callingUid
4680 + " does not have permission to uri " + uri);
4681 //}
4682 }
4683
4684 // Go through all of the permissions and remove any that match.
4685 final List<String> SEGMENTS = uri.getPathSegments();
4686 if (SEGMENTS != null) {
4687 final int NS = SEGMENTS.size();
4688 int N = mGrantedUriPermissions.size();
4689 for (int i=0; i<N; i++) {
4690 HashMap<Uri, UriPermission> perms
4691 = mGrantedUriPermissions.valueAt(i);
4692 Iterator<UriPermission> it = perms.values().iterator();
4693 toploop:
4694 while (it.hasNext()) {
4695 UriPermission perm = it.next();
4696 Uri targetUri = perm.uri;
4697 if (!authority.equals(targetUri.getAuthority())) {
4698 continue;
4699 }
4700 List<String> targetSegments = targetUri.getPathSegments();
4701 if (targetSegments == null) {
4702 continue;
4703 }
4704 if (targetSegments.size() < NS) {
4705 continue;
4706 }
4707 for (int j=0; j<NS; j++) {
4708 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4709 continue toploop;
4710 }
4711 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004712 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004713 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004714 perm.clearModes(modeFlags);
4715 if (perm.modeFlags == 0) {
4716 it.remove();
4717 }
4718 }
4719 if (perms.size() == 0) {
4720 mGrantedUriPermissions.remove(
4721 mGrantedUriPermissions.keyAt(i));
4722 N--;
4723 i--;
4724 }
4725 }
4726 }
4727 }
4728
4729 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4730 int modeFlags) {
4731 synchronized(this) {
4732 final ProcessRecord r = getRecordForAppLocked(caller);
4733 if (r == null) {
4734 throw new SecurityException("Unable to find app for caller "
4735 + caller
4736 + " when revoking permission to uri " + uri);
4737 }
4738 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004739 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 return;
4741 }
4742
4743 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4744 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4745 if (modeFlags == 0) {
4746 return;
4747 }
4748
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004749 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004750
4751 final String authority = uri.getAuthority();
4752 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004753 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 if (cpr != null) {
4755 pi = cpr.info;
4756 } else {
4757 try {
4758 pi = pm.resolveContentProvider(authority,
4759 PackageManager.GET_URI_PERMISSION_PATTERNS);
4760 } catch (RemoteException ex) {
4761 }
4762 }
4763 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004764 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004765 return;
4766 }
4767
4768 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4769 }
4770 }
4771
Dianne Hackborn7e269642010-08-25 19:50:20 -07004772 @Override
4773 public IBinder newUriPermissionOwner(String name) {
4774 synchronized(this) {
4775 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4776 return owner.getExternalTokenLocked();
4777 }
4778 }
4779
4780 @Override
4781 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4782 Uri uri, int modeFlags) {
4783 synchronized(this) {
4784 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4785 if (owner == null) {
4786 throw new IllegalArgumentException("Unknown owner: " + token);
4787 }
4788 if (fromUid != Binder.getCallingUid()) {
4789 if (Binder.getCallingUid() != Process.myUid()) {
4790 // Only system code can grant URI permissions on behalf
4791 // of other users.
4792 throw new SecurityException("nice try");
4793 }
4794 }
4795 if (targetPkg == null) {
4796 throw new IllegalArgumentException("null target");
4797 }
4798 if (uri == null) {
4799 throw new IllegalArgumentException("null uri");
4800 }
4801
4802 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4803 }
4804 }
4805
4806 @Override
4807 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4808 synchronized(this) {
4809 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4810 if (owner == null) {
4811 throw new IllegalArgumentException("Unknown owner: " + token);
4812 }
4813
4814 if (uri == null) {
4815 owner.removeUriPermissionsLocked(mode);
4816 } else {
4817 owner.removeUriPermissionLocked(uri, mode);
4818 }
4819 }
4820 }
4821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4823 synchronized (this) {
4824 ProcessRecord app =
4825 who != null ? getRecordForAppLocked(who) : null;
4826 if (app == null) return;
4827
4828 Message msg = Message.obtain();
4829 msg.what = WAIT_FOR_DEBUGGER_MSG;
4830 msg.obj = app;
4831 msg.arg1 = waiting ? 1 : 0;
4832 mHandler.sendMessage(msg);
4833 }
4834 }
4835
4836 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004837 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4838 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004839 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004840 outInfo.threshold = homeAppMem;
4841 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4842 outInfo.hiddenAppThreshold = hiddenAppMem;
4843 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4844 ProcessList.SECONDARY_SERVER_ADJ);
4845 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4846 ProcessList.VISIBLE_APP_ADJ);
4847 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4848 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004849 }
4850
4851 // =========================================================
4852 // TASK MANAGEMENT
4853 // =========================================================
4854
4855 public List getTasks(int maxNum, int flags,
4856 IThumbnailReceiver receiver) {
4857 ArrayList list = new ArrayList();
4858
4859 PendingThumbnailsRecord pending = null;
4860 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004861 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862
4863 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004864 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004865 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4866 + ", receiver=" + receiver);
4867
4868 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4869 != PackageManager.PERMISSION_GRANTED) {
4870 if (receiver != null) {
4871 // If the caller wants to wait for pending thumbnails,
4872 // it ain't gonna get them.
4873 try {
4874 receiver.finished();
4875 } catch (RemoteException ex) {
4876 }
4877 }
4878 String msg = "Permission Denial: getTasks() from pid="
4879 + Binder.getCallingPid()
4880 + ", uid=" + Binder.getCallingUid()
4881 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004882 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004883 throw new SecurityException(msg);
4884 }
4885
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004886 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004887 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004888 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004889 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004890 TaskRecord curTask = null;
4891 int numActivities = 0;
4892 int numRunning = 0;
4893 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004894 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004895 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004896 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897
4898 // Initialize state for next task if needed.
4899 if (top == null ||
4900 (top.state == ActivityState.INITIALIZING
4901 && top.task == r.task)) {
4902 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004903 curTask = r.task;
4904 numActivities = numRunning = 0;
4905 }
4906
4907 // Add 'r' into the current task.
4908 numActivities++;
4909 if (r.app != null && r.app.thread != null) {
4910 numRunning++;
4911 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004912
Joe Onorato8a9b2202010-02-26 18:56:32 -08004913 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004914 TAG, r.intent.getComponent().flattenToShortString()
4915 + ": task=" + r.task);
4916
4917 // If the next one is a different task, generate a new
4918 // TaskInfo entry for what we have.
4919 if (next == null || next.task != curTask) {
4920 ActivityManager.RunningTaskInfo ci
4921 = new ActivityManager.RunningTaskInfo();
4922 ci.id = curTask.taskId;
4923 ci.baseActivity = r.intent.getComponent();
4924 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004925 if (top.thumbHolder != null) {
4926 ci.description = top.thumbHolder.lastDescription;
4927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004928 ci.numActivities = numActivities;
4929 ci.numRunning = numRunning;
4930 //System.out.println(
4931 // "#" + maxNum + ": " + " descr=" + ci.description);
4932 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004933 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004934 TAG, "State=" + top.state + "Idle=" + top.idle
4935 + " app=" + top.app
4936 + " thr=" + (top.app != null ? top.app.thread : null));
4937 if (top.state == ActivityState.RESUMED
4938 || top.state == ActivityState.PAUSING) {
4939 if (top.idle && top.app != null
4940 && top.app.thread != null) {
4941 topRecord = top;
4942 topThumbnail = top.app.thread;
4943 } else {
4944 top.thumbnailNeeded = true;
4945 }
4946 }
4947 if (pending == null) {
4948 pending = new PendingThumbnailsRecord(receiver);
4949 }
4950 pending.pendingRecords.add(top);
4951 }
4952 list.add(ci);
4953 maxNum--;
4954 top = null;
4955 }
4956 }
4957
4958 if (pending != null) {
4959 mPendingThumbnails.add(pending);
4960 }
4961 }
4962
Joe Onorato8a9b2202010-02-26 18:56:32 -08004963 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964
4965 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004966 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004967 try {
4968 topThumbnail.requestThumbnail(topRecord);
4969 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004970 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 sendPendingThumbnail(null, topRecord, null, null, true);
4972 }
4973 }
4974
4975 if (pending == null && receiver != null) {
4976 // In this case all thumbnails were available and the client
4977 // is being asked to be told when the remaining ones come in...
4978 // which is unusually, since the top-most currently running
4979 // activity should never have a canned thumbnail! Oh well.
4980 try {
4981 receiver.finished();
4982 } catch (RemoteException ex) {
4983 }
4984 }
4985
4986 return list;
4987 }
4988
4989 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4990 int flags) {
4991 synchronized (this) {
4992 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4993 "getRecentTasks()");
4994
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004995 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07004996
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004997 final int N = mRecentTasks.size();
4998 ArrayList<ActivityManager.RecentTaskInfo> res
4999 = new ArrayList<ActivityManager.RecentTaskInfo>(
5000 maxNum < N ? maxNum : N);
5001 for (int i=0; i<N && maxNum > 0; i++) {
5002 TaskRecord tr = mRecentTasks.get(i);
5003 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5004 || (tr.intent == null)
5005 || ((tr.intent.getFlags()
5006 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5007 ActivityManager.RecentTaskInfo rti
5008 = new ActivityManager.RecentTaskInfo();
5009 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005010 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005011 rti.baseIntent = new Intent(
5012 tr.intent != null ? tr.intent : tr.affinityIntent);
5013 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005014 rti.description = tr.lastDescription;
5015
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005016 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5017 // Check whether this activity is currently available.
5018 try {
5019 if (rti.origActivity != null) {
5020 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5021 continue;
5022 }
5023 } else if (rti.baseIntent != null) {
5024 if (pm.queryIntentActivities(rti.baseIntent,
5025 null, 0) == null) {
5026 continue;
5027 }
5028 }
5029 } catch (RemoteException e) {
5030 // Will never happen.
5031 }
5032 }
5033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005034 res.add(rti);
5035 maxNum--;
5036 }
5037 }
5038 return res;
5039 }
5040 }
5041
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005042 private TaskRecord taskForIdLocked(int id) {
5043 final int N = mRecentTasks.size();
5044 for (int i=0; i<N; i++) {
5045 TaskRecord tr = mRecentTasks.get(i);
5046 if (tr.taskId == id) {
5047 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005048 }
5049 }
5050 return null;
5051 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005052
5053 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5054 synchronized (this) {
5055 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5056 "getTaskThumbnails()");
5057 TaskRecord tr = taskForIdLocked(id);
5058 if (tr != null) {
5059 return mMainStack.getTaskThumbnailsLocked(tr);
5060 }
5061 }
5062 return null;
5063 }
5064
5065 public boolean removeSubTask(int taskId, int subTaskIndex) {
5066 synchronized (this) {
5067 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5068 "removeSubTask()");
5069 long ident = Binder.clearCallingIdentity();
5070 try {
5071 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5072 } finally {
5073 Binder.restoreCallingIdentity(ident);
5074 }
5075 }
5076 }
5077
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005078 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005079 TaskRecord tr = root.task;
5080 Intent baseIntent = new Intent(
5081 tr.intent != null ? tr.intent : tr.affinityIntent);
5082 ComponentName component = baseIntent.getComponent();
5083 if (component == null) {
5084 Slog.w(TAG, "Now component for base intent of task: " + tr);
5085 return;
5086 }
5087
5088 // Find any running services associated with this app.
5089 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5090 for (ServiceRecord sr : mServices.values()) {
5091 if (sr.packageName.equals(component.getPackageName())) {
5092 services.add(sr);
5093 }
5094 }
5095
5096 // Take care of any running services associated with the app.
5097 for (int i=0; i<services.size(); i++) {
5098 ServiceRecord sr = services.get(i);
5099 if (sr.startRequested) {
5100 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005101 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005102 stopServiceLocked(sr);
5103 } else {
5104 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5105 sr.makeNextStartId(), baseIntent, -1));
5106 if (sr.app != null && sr.app.thread != null) {
5107 sendServiceArgsLocked(sr, false);
5108 }
5109 }
5110 }
5111 }
5112
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005113 if (killProcesses) {
5114 // Find any running processes associated with this app.
5115 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5116 SparseArray<ProcessRecord> appProcs
5117 = mProcessNames.getMap().get(component.getPackageName());
5118 if (appProcs != null) {
5119 for (int i=0; i<appProcs.size(); i++) {
5120 procs.add(appProcs.valueAt(i));
5121 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005122 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005123
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005124 // Kill the running processes.
5125 for (int i=0; i<procs.size(); i++) {
5126 ProcessRecord pr = procs.get(i);
5127 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5128 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5129 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5130 pr.processName, pr.setAdj, "remove task");
5131 Process.killProcessQuiet(pr.pid);
5132 } else {
5133 pr.waitingToKill = "remove task";
5134 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005135 }
5136 }
5137 }
5138
5139 public boolean removeTask(int taskId, int flags) {
5140 synchronized (this) {
5141 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5142 "removeTask()");
5143 long ident = Binder.clearCallingIdentity();
5144 try {
5145 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5146 if (r != null) {
5147 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005148 cleanUpRemovedTaskLocked(r,
5149 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005150 return true;
5151 }
5152 } finally {
5153 Binder.restoreCallingIdentity(ident);
5154 }
5155 }
5156 return false;
5157 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005158
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005159 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5160 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005161 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005162 TaskRecord jt = startTask;
5163
5164 // First look backwards
5165 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005166 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005167 if (r.task != jt) {
5168 jt = r.task;
5169 if (affinity.equals(jt.affinity)) {
5170 return j;
5171 }
5172 }
5173 }
5174
5175 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005176 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005177 jt = startTask;
5178 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005179 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005180 if (r.task != jt) {
5181 if (affinity.equals(jt.affinity)) {
5182 return j;
5183 }
5184 jt = r.task;
5185 }
5186 }
5187
5188 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005189 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005190 return N-1;
5191 }
5192
5193 return -1;
5194 }
5195
5196 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005197 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005199 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005200 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5201 "moveTaskToFront()");
5202
5203 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005204 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5205 Binder.getCallingUid(), "Task to front")) {
5206 return;
5207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005208 final long origId = Binder.clearCallingIdentity();
5209 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005210 TaskRecord tr = taskForIdLocked(task);
5211 if (tr != null) {
5212 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5213 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005214 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005215 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5216 // Caller wants the home activity moved with it. To accomplish this,
5217 // we'll just move the home task to the top first.
5218 mMainStack.moveHomeToFrontLocked();
5219 }
5220 mMainStack.moveTaskToFrontLocked(tr, null);
5221 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005222 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005223 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5224 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005225 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005226 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5227 mMainStack.mUserLeaving = true;
5228 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005229 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5230 // Caller wants the home activity moved with it. To accomplish this,
5231 // we'll just move the home task to the top first.
5232 mMainStack.moveHomeToFrontLocked();
5233 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005234 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005235 return;
5236 }
5237 }
5238 } finally {
5239 Binder.restoreCallingIdentity(origId);
5240 }
5241 }
5242 }
5243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 public void moveTaskToBack(int task) {
5245 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5246 "moveTaskToBack()");
5247
5248 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005249 if (mMainStack.mResumedActivity != null
5250 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005251 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5252 Binder.getCallingUid(), "Task to back")) {
5253 return;
5254 }
5255 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005257 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005258 Binder.restoreCallingIdentity(origId);
5259 }
5260 }
5261
5262 /**
5263 * Moves an activity, and all of the other activities within the same task, to the bottom
5264 * of the history stack. The activity's order within the task is unchanged.
5265 *
5266 * @param token A reference to the activity we wish to move
5267 * @param nonRoot If false then this only works if the activity is the root
5268 * of a task; if true it will work for any activity in a task.
5269 * @return Returns true if the move completed, false if not.
5270 */
5271 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5272 synchronized(this) {
5273 final long origId = Binder.clearCallingIdentity();
5274 int taskId = getTaskForActivityLocked(token, !nonRoot);
5275 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005276 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005277 }
5278 Binder.restoreCallingIdentity(origId);
5279 }
5280 return false;
5281 }
5282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005283 public void moveTaskBackwards(int task) {
5284 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5285 "moveTaskBackwards()");
5286
5287 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005288 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5289 Binder.getCallingUid(), "Task backwards")) {
5290 return;
5291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005292 final long origId = Binder.clearCallingIdentity();
5293 moveTaskBackwardsLocked(task);
5294 Binder.restoreCallingIdentity(origId);
5295 }
5296 }
5297
5298 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005299 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005300 }
5301
5302 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5303 synchronized(this) {
5304 return getTaskForActivityLocked(token, onlyRoot);
5305 }
5306 }
5307
5308 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005309 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005310 TaskRecord lastTask = null;
5311 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005312 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005313 if (r == token) {
5314 if (!onlyRoot || lastTask != r.task) {
5315 return r.task.taskId;
5316 }
5317 return -1;
5318 }
5319 lastTask = r.task;
5320 }
5321
5322 return -1;
5323 }
5324
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005325 public void finishOtherInstances(IBinder token, ComponentName className) {
5326 synchronized(this) {
5327 final long origId = Binder.clearCallingIdentity();
5328
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005329 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005330 TaskRecord lastTask = null;
5331 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005332 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005333 if (r.realActivity.equals(className)
5334 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005335 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005336 null, "others")) {
5337 i--;
5338 N--;
5339 }
5340 }
5341 lastTask = r.task;
5342 }
5343
5344 Binder.restoreCallingIdentity(origId);
5345 }
5346 }
5347
5348 // =========================================================
5349 // THUMBNAILS
5350 // =========================================================
5351
5352 public void reportThumbnail(IBinder token,
5353 Bitmap thumbnail, CharSequence description) {
5354 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5355 final long origId = Binder.clearCallingIdentity();
5356 sendPendingThumbnail(null, token, thumbnail, description, true);
5357 Binder.restoreCallingIdentity(origId);
5358 }
5359
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005360 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005361 Bitmap thumbnail, CharSequence description, boolean always) {
5362 TaskRecord task = null;
5363 ArrayList receivers = null;
5364
5365 //System.out.println("Send pending thumbnail: " + r);
5366
5367 synchronized(this) {
5368 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005369 r = mMainStack.isInStackLocked(token);
5370 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005371 return;
5372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005373 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005374 if (thumbnail == null && r.thumbHolder != null) {
5375 thumbnail = r.thumbHolder.lastThumbnail;
5376 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005377 }
5378 if (thumbnail == null && !always) {
5379 // If there is no thumbnail, and this entry is not actually
5380 // going away, then abort for now and pick up the next
5381 // thumbnail we get.
5382 return;
5383 }
5384 task = r.task;
5385
5386 int N = mPendingThumbnails.size();
5387 int i=0;
5388 while (i<N) {
5389 PendingThumbnailsRecord pr =
5390 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5391 //System.out.println("Looking in " + pr.pendingRecords);
5392 if (pr.pendingRecords.remove(r)) {
5393 if (receivers == null) {
5394 receivers = new ArrayList();
5395 }
5396 receivers.add(pr);
5397 if (pr.pendingRecords.size() == 0) {
5398 pr.finished = true;
5399 mPendingThumbnails.remove(i);
5400 N--;
5401 continue;
5402 }
5403 }
5404 i++;
5405 }
5406 }
5407
5408 if (receivers != null) {
5409 final int N = receivers.size();
5410 for (int i=0; i<N; i++) {
5411 try {
5412 PendingThumbnailsRecord pr =
5413 (PendingThumbnailsRecord)receivers.get(i);
5414 pr.receiver.newThumbnail(
5415 task != null ? task.taskId : -1, thumbnail, description);
5416 if (pr.finished) {
5417 pr.receiver.finished();
5418 }
5419 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005420 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005421 }
5422 }
5423 }
5424 }
5425
5426 // =========================================================
5427 // CONTENT PROVIDERS
5428 // =========================================================
5429
Jeff Brown10e89712011-07-08 18:52:57 -07005430 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5431 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005433 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005434 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005435 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 } catch (RemoteException ex) {
5437 }
5438 if (providers != null) {
5439 final int N = providers.size();
5440 for (int i=0; i<N; i++) {
5441 ProviderInfo cpi =
5442 (ProviderInfo)providers.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07005443 ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005444 if (cpr == null) {
5445 cpr = new ContentProviderRecord(cpi, app.info);
5446 mProvidersByClass.put(cpi.name, cpr);
5447 }
5448 app.pubProviders.put(cpi.name, cpr);
5449 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005450 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005451 }
5452 }
5453 return providers;
5454 }
5455
5456 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005457 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005458 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5459 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5460 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005461 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005462 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 return null;
5464 }
5465 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005466 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005467 == PackageManager.PERMISSION_GRANTED) {
5468 return null;
5469 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005470
5471 PathPermission[] pps = cpi.pathPermissions;
5472 if (pps != null) {
5473 int i = pps.length;
5474 while (i > 0) {
5475 i--;
5476 PathPermission pp = pps[i];
5477 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005478 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005479 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005480 return null;
5481 }
5482 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005483 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005484 == PackageManager.PERMISSION_GRANTED) {
5485 return null;
5486 }
5487 }
5488 }
5489
Dianne Hackbornb424b632010-08-18 15:59:05 -07005490 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5491 if (perms != null) {
5492 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5493 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5494 return null;
5495 }
5496 }
5497 }
5498
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005499 String msg;
5500 if (!cpi.exported) {
5501 msg = "Permission Denial: opening provider " + cpi.name
5502 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5503 + ", uid=" + callingUid + ") that is not exported from uid "
5504 + cpi.applicationInfo.uid;
5505 } else {
5506 msg = "Permission Denial: opening provider " + cpi.name
5507 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5508 + ", uid=" + callingUid + ") requires "
5509 + cpi.readPermission + " or " + cpi.writePermission;
5510 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005511 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005512 return msg;
5513 }
5514
5515 private final ContentProviderHolder getContentProviderImpl(
5516 IApplicationThread caller, String name) {
5517 ContentProviderRecord cpr;
5518 ProviderInfo cpi = null;
5519
5520 synchronized(this) {
5521 ProcessRecord r = null;
5522 if (caller != null) {
5523 r = getRecordForAppLocked(caller);
5524 if (r == null) {
5525 throw new SecurityException(
5526 "Unable to find app for caller " + caller
5527 + " (pid=" + Binder.getCallingPid()
5528 + ") when getting content provider " + name);
5529 }
5530 }
5531
5532 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005533 cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005534 if (cpr != null) {
5535 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005536 String msg;
5537 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5538 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005539 }
5540
5541 if (r != null && cpr.canRunHere(r)) {
5542 // This provider has been published or is in the process
5543 // of being published... but it is also allowed to run
5544 // in the caller's process, so don't make a connection
5545 // and just let the caller instantiate its own instance.
5546 if (cpr.provider != null) {
5547 // don't give caller the provider object, it needs
5548 // to make its own.
5549 cpr = new ContentProviderRecord(cpr);
5550 }
5551 return cpr;
5552 }
5553
5554 final long origId = Binder.clearCallingIdentity();
5555
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005556 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005557 // return it right away.
5558 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005559 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005560 "Adding provider requested by "
5561 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005562 + cpr.info.processName);
5563 Integer cnt = r.conProviders.get(cpr);
5564 if (cnt == null) {
5565 r.conProviders.put(cpr, new Integer(1));
5566 } else {
5567 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005569 cpr.clients.add(r);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005570 if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005571 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005572 // make sure to count it as being accessed and thus
5573 // back up on the LRU list. This is good because
5574 // content providers are often expensive to start.
5575 updateLruProcessLocked(cpr.app, false, true);
5576 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005577 } else {
5578 cpr.externals++;
5579 }
5580
5581 if (cpr.app != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005582 updateOomAdjLocked(cpr.app);
5583 }
5584
5585 Binder.restoreCallingIdentity(origId);
5586
5587 } else {
5588 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005589 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005590 resolveContentProvider(name,
5591 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 } catch (RemoteException ex) {
5593 }
5594 if (cpi == null) {
5595 return null;
5596 }
5597
Dianne Hackbornb424b632010-08-18 15:59:05 -07005598 String msg;
5599 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5600 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005601 }
5602
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005603 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005604 && !cpi.processName.equals("system")) {
5605 // If this content provider does not run in the system
5606 // process, and the system is not yet ready to run other
5607 // processes, then fail fast instead of hanging.
5608 throw new IllegalArgumentException(
5609 "Attempt to launch content provider before system ready");
5610 }
5611
Dianne Hackborn860755f2010-06-03 18:47:52 -07005612 cpr = mProvidersByClass.get(cpi.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005613 final boolean firstClass = cpr == null;
5614 if (firstClass) {
5615 try {
5616 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005617 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005618 getApplicationInfo(
5619 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005620 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005621 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005622 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 + cpi.name);
5624 return null;
5625 }
5626 cpr = new ContentProviderRecord(cpi, ai);
5627 } catch (RemoteException ex) {
5628 // pm is in same process, this will never happen.
5629 }
5630 }
5631
5632 if (r != null && cpr.canRunHere(r)) {
5633 // If this is a multiprocess provider, then just return its
5634 // info and allow the caller to instantiate it. Only do
5635 // this if the provider is the same user as the caller's
5636 // process, or can run as root (so can be in any process).
5637 return cpr;
5638 }
5639
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005640 if (DEBUG_PROVIDER) {
5641 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005642 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005643 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005644 }
5645
5646 // This is single process, and our app is now connecting to it.
5647 // See if we are already in the process of launching this
5648 // provider.
5649 final int N = mLaunchingProviders.size();
5650 int i;
5651 for (i=0; i<N; i++) {
5652 if (mLaunchingProviders.get(i) == cpr) {
5653 break;
5654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005655 }
5656
5657 // If the provider is not already being launched, then get it
5658 // started.
5659 if (i >= N) {
5660 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005661
5662 try {
5663 // Content provider is now in use, its package can't be stopped.
5664 try {
5665 AppGlobals.getPackageManager().setPackageStoppedState(
5666 cpr.appInfo.packageName, false);
5667 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005668 } catch (IllegalArgumentException e) {
5669 Slog.w(TAG, "Failed trying to unstop package "
5670 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005671 }
5672
5673 ProcessRecord proc = startProcessLocked(cpi.processName,
5674 cpr.appInfo, false, 0, "content provider",
5675 new ComponentName(cpi.applicationInfo.packageName,
5676 cpi.name), false);
5677 if (proc == null) {
5678 Slog.w(TAG, "Unable to launch app "
5679 + cpi.applicationInfo.packageName + "/"
5680 + cpi.applicationInfo.uid + " for provider "
5681 + name + ": process is bad");
5682 return null;
5683 }
5684 cpr.launchingApp = proc;
5685 mLaunchingProviders.add(cpr);
5686 } finally {
5687 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 }
5690
5691 // Make sure the provider is published (the same provider class
5692 // may be published under multiple names).
5693 if (firstClass) {
5694 mProvidersByClass.put(cpi.name, cpr);
5695 }
5696 mProvidersByName.put(name, cpr);
5697
5698 if (r != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005699 if (DEBUG_PROVIDER) Slog.v(TAG,
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005700 "Adding provider requested by "
5701 + r.processName + " from process "
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005702 + cpr.info.processName);
5703 Integer cnt = r.conProviders.get(cpr);
5704 if (cnt == null) {
5705 r.conProviders.put(cpr, new Integer(1));
5706 } else {
5707 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5708 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005709 cpr.clients.add(r);
5710 } else {
5711 cpr.externals++;
5712 }
5713 }
5714 }
5715
5716 // Wait for the provider to be published...
5717 synchronized (cpr) {
5718 while (cpr.provider == null) {
5719 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005720 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005721 + cpi.applicationInfo.packageName + "/"
5722 + cpi.applicationInfo.uid + " for provider "
5723 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005724 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005725 cpi.applicationInfo.packageName,
5726 cpi.applicationInfo.uid, name);
5727 return null;
5728 }
5729 try {
5730 cpr.wait();
5731 } catch (InterruptedException ex) {
5732 }
5733 }
5734 }
5735 return cpr;
5736 }
5737
5738 public final ContentProviderHolder getContentProvider(
5739 IApplicationThread caller, String name) {
5740 if (caller == null) {
5741 String msg = "null IApplicationThread when getting content provider "
5742 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005743 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744 throw new SecurityException(msg);
5745 }
5746
5747 return getContentProviderImpl(caller, name);
5748 }
5749
5750 private ContentProviderHolder getContentProviderExternal(String name) {
5751 return getContentProviderImpl(null, name);
5752 }
5753
5754 /**
5755 * Drop a content provider from a ProcessRecord's bookkeeping
5756 * @param cpr
5757 */
5758 public void removeContentProvider(IApplicationThread caller, String name) {
5759 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005760 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005762 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005763 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005764 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005765 return;
5766 }
5767 final ProcessRecord r = getRecordForAppLocked(caller);
5768 if (r == null) {
5769 throw new SecurityException(
5770 "Unable to find app for caller " + caller +
5771 " when removing content provider " + name);
5772 }
5773 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005774 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
Joe Onorato8a9b2202010-02-26 18:56:32 -08005775 if (DEBUG_PROVIDER) Slog.v(TAG, "Removing provider requested by "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005776 + r.info.processName + " from process "
5777 + localCpr.appInfo.processName);
5778 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005779 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005780 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005781 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005782 return;
5783 } else {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005784 Integer cnt = r.conProviders.get(localCpr);
5785 if (cnt == null || cnt.intValue() <= 1) {
5786 localCpr.clients.remove(r);
5787 r.conProviders.remove(localCpr);
5788 } else {
5789 r.conProviders.put(localCpr, new Integer(cnt.intValue()-1));
5790 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005791 }
5792 updateOomAdjLocked();
5793 }
5794 }
5795
5796 private void removeContentProviderExternal(String name) {
5797 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005798 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799 if(cpr == null) {
5800 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005801 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005802 return;
5803 }
5804
5805 //update content provider record entry info
Dianne Hackborn860755f2010-06-03 18:47:52 -07005806 ContentProviderRecord localCpr = mProvidersByClass.get(cpr.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005807 localCpr.externals--;
5808 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005809 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 }
5811 updateOomAdjLocked();
5812 }
5813 }
5814
5815 public final void publishContentProviders(IApplicationThread caller,
5816 List<ContentProviderHolder> providers) {
5817 if (providers == null) {
5818 return;
5819 }
5820
5821 synchronized(this) {
5822 final ProcessRecord r = getRecordForAppLocked(caller);
5823 if (r == null) {
5824 throw new SecurityException(
5825 "Unable to find app for caller " + caller
5826 + " (pid=" + Binder.getCallingPid()
5827 + ") when publishing content providers");
5828 }
5829
5830 final long origId = Binder.clearCallingIdentity();
5831
5832 final int N = providers.size();
5833 for (int i=0; i<N; i++) {
5834 ContentProviderHolder src = providers.get(i);
5835 if (src == null || src.info == null || src.provider == null) {
5836 continue;
5837 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005838 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 if (dst != null) {
5840 mProvidersByClass.put(dst.info.name, dst);
5841 String names[] = dst.info.authority.split(";");
5842 for (int j = 0; j < names.length; j++) {
5843 mProvidersByName.put(names[j], dst);
5844 }
5845
5846 int NL = mLaunchingProviders.size();
5847 int j;
5848 for (j=0; j<NL; j++) {
5849 if (mLaunchingProviders.get(j) == dst) {
5850 mLaunchingProviders.remove(j);
5851 j--;
5852 NL--;
5853 }
5854 }
5855 synchronized (dst) {
5856 dst.provider = src.provider;
5857 dst.app = r;
5858 dst.notifyAll();
5859 }
5860 updateOomAdjLocked(r);
5861 }
5862 }
5863
5864 Binder.restoreCallingIdentity(origId);
5865 }
5866 }
5867
5868 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005869 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005870 synchronized (mSelf) {
5871 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5872 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005873 if (providers != null) {
5874 for (int i=providers.size()-1; i>=0; i--) {
5875 ProviderInfo pi = (ProviderInfo)providers.get(i);
5876 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5877 Slog.w(TAG, "Not installing system proc provider " + pi.name
5878 + ": not system .apk");
5879 providers.remove(i);
5880 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005881 }
5882 }
5883 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005884 if (providers != null) {
5885 mSystemThread.installSystemProviders(providers);
5886 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005887
5888 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005889
5890 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005891 }
5892
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005893 /**
5894 * Allows app to retrieve the MIME type of a URI without having permission
5895 * to access its content provider.
5896 *
5897 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5898 *
5899 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5900 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5901 */
5902 public String getProviderMimeType(Uri uri) {
5903 final String name = uri.getAuthority();
5904 final long ident = Binder.clearCallingIdentity();
5905 ContentProviderHolder holder = null;
5906
5907 try {
5908 holder = getContentProviderExternal(name);
5909 if (holder != null) {
5910 return holder.provider.getType(uri);
5911 }
5912 } catch (RemoteException e) {
5913 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5914 return null;
5915 } finally {
5916 if (holder != null) {
5917 removeContentProviderExternal(name);
5918 }
5919 Binder.restoreCallingIdentity(ident);
5920 }
5921
5922 return null;
5923 }
5924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005925 // =========================================================
5926 // GLOBAL MANAGEMENT
5927 // =========================================================
5928
5929 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5930 ApplicationInfo info, String customProcess) {
5931 String proc = customProcess != null ? customProcess : info.processName;
5932 BatteryStatsImpl.Uid.Proc ps = null;
5933 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5934 synchronized (stats) {
5935 ps = stats.getProcessStatsLocked(info.uid, proc);
5936 }
5937 return new ProcessRecord(ps, thread, info, proc);
5938 }
5939
5940 final ProcessRecord addAppLocked(ApplicationInfo info) {
5941 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5942
5943 if (app == null) {
5944 app = newProcessRecordLocked(null, info, null);
5945 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005946 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 }
5948
Dianne Hackborne7f97212011-02-24 14:40:20 -08005949 // This package really, really can not be stopped.
5950 try {
5951 AppGlobals.getPackageManager().setPackageStoppedState(
5952 info.packageName, false);
5953 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005954 } catch (IllegalArgumentException e) {
5955 Slog.w(TAG, "Failed trying to unstop package "
5956 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005957 }
5958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005959 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
5960 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
5961 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07005962 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005963 }
5964 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
5965 mPersistentStartingProcesses.add(app);
5966 startProcessLocked(app, "added application", app.processName);
5967 }
5968
5969 return app;
5970 }
5971
5972 public void unhandledBack() {
5973 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
5974 "unhandledBack()");
5975
5976 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005977 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08005978 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005979 TAG, "Performing unhandledBack(): stack size = " + count);
5980 if (count > 1) {
5981 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005982 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005983 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
5984 Binder.restoreCallingIdentity(origId);
5985 }
5986 }
5987 }
5988
5989 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
5990 String name = uri.getAuthority();
5991 ContentProviderHolder cph = getContentProviderExternal(name);
5992 ParcelFileDescriptor pfd = null;
5993 if (cph != null) {
5994 // We record the binder invoker's uid in thread-local storage before
5995 // going to the content provider to open the file. Later, in the code
5996 // that handles all permissions checks, we look for this uid and use
5997 // that rather than the Activity Manager's own uid. The effect is that
5998 // we do the check against the caller's permissions even though it looks
5999 // to the content provider like the Activity Manager itself is making
6000 // the request.
6001 sCallerIdentity.set(new Identity(
6002 Binder.getCallingPid(), Binder.getCallingUid()));
6003 try {
6004 pfd = cph.provider.openFile(uri, "r");
6005 } catch (FileNotFoundException e) {
6006 // do nothing; pfd will be returned null
6007 } finally {
6008 // Ensure that whatever happens, we clean up the identity state
6009 sCallerIdentity.remove();
6010 }
6011
6012 // We've got the fd now, so we're done with the provider.
6013 removeContentProviderExternal(name);
6014 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006015 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006016 }
6017 return pfd;
6018 }
6019
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006020 // Actually is sleeping or shutting down or whatever else in the future
6021 // is an inactive state.
6022 public boolean isSleeping() {
6023 return mSleeping || mShuttingDown;
6024 }
6025
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 public void goingToSleep() {
6027 synchronized(this) {
6028 mSleeping = true;
6029 mWindowManager.setEventDispatching(false);
6030
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006031 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006032
6033 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006034 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006035 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6036 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006037 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006038 }
6039 }
6040
Dianne Hackborn55280a92009-05-07 15:53:46 -07006041 public boolean shutdown(int timeout) {
6042 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6043 != PackageManager.PERMISSION_GRANTED) {
6044 throw new SecurityException("Requires permission "
6045 + android.Manifest.permission.SHUTDOWN);
6046 }
6047
6048 boolean timedout = false;
6049
6050 synchronized(this) {
6051 mShuttingDown = true;
6052 mWindowManager.setEventDispatching(false);
6053
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006054 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006055 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006056 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006057 while (mMainStack.mResumedActivity != null
6058 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006059 long delay = endTime - System.currentTimeMillis();
6060 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006061 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006062 timedout = true;
6063 break;
6064 }
6065 try {
6066 this.wait();
6067 } catch (InterruptedException e) {
6068 }
6069 }
6070 }
6071 }
6072
6073 mUsageStatsService.shutdown();
6074 mBatteryStatsService.shutdown();
6075
6076 return timedout;
6077 }
6078
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006079 public final void activitySlept(IBinder token) {
6080 if (localLOGV) Slog.v(
6081 TAG, "Activity slept: token=" + token);
6082
6083 ActivityRecord r = null;
6084
6085 final long origId = Binder.clearCallingIdentity();
6086
6087 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006088 r = mMainStack.isInStackLocked(token);
6089 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006090 mMainStack.activitySleptLocked(r);
6091 }
6092 }
6093
6094 Binder.restoreCallingIdentity(origId);
6095 }
6096
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 public void wakingUp() {
6098 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006099 mWindowManager.setEventDispatching(true);
6100 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006101 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006102 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103 }
6104 }
6105
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006106 public void stopAppSwitches() {
6107 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6108 != PackageManager.PERMISSION_GRANTED) {
6109 throw new SecurityException("Requires permission "
6110 + android.Manifest.permission.STOP_APP_SWITCHES);
6111 }
6112
6113 synchronized(this) {
6114 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6115 + APP_SWITCH_DELAY_TIME;
6116 mDidAppSwitch = false;
6117 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6118 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6119 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6120 }
6121 }
6122
6123 public void resumeAppSwitches() {
6124 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6125 != PackageManager.PERMISSION_GRANTED) {
6126 throw new SecurityException("Requires permission "
6127 + android.Manifest.permission.STOP_APP_SWITCHES);
6128 }
6129
6130 synchronized(this) {
6131 // Note that we don't execute any pending app switches... we will
6132 // let those wait until either the timeout, or the next start
6133 // activity request.
6134 mAppSwitchesAllowedTime = 0;
6135 }
6136 }
6137
6138 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6139 String name) {
6140 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6141 return true;
6142 }
6143
6144 final int perm = checkComponentPermission(
6145 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006146 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006147 if (perm == PackageManager.PERMISSION_GRANTED) {
6148 return true;
6149 }
6150
Joe Onorato8a9b2202010-02-26 18:56:32 -08006151 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006152 return false;
6153 }
6154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006155 public void setDebugApp(String packageName, boolean waitForDebugger,
6156 boolean persistent) {
6157 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6158 "setDebugApp()");
6159
6160 // Note that this is not really thread safe if there are multiple
6161 // callers into it at the same time, but that's not a situation we
6162 // care about.
6163 if (persistent) {
6164 final ContentResolver resolver = mContext.getContentResolver();
6165 Settings.System.putString(
6166 resolver, Settings.System.DEBUG_APP,
6167 packageName);
6168 Settings.System.putInt(
6169 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6170 waitForDebugger ? 1 : 0);
6171 }
6172
6173 synchronized (this) {
6174 if (!persistent) {
6175 mOrigDebugApp = mDebugApp;
6176 mOrigWaitForDebugger = mWaitForDebugger;
6177 }
6178 mDebugApp = packageName;
6179 mWaitForDebugger = waitForDebugger;
6180 mDebugTransient = !persistent;
6181 if (packageName != null) {
6182 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006183 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006184 Binder.restoreCallingIdentity(origId);
6185 }
6186 }
6187 }
6188
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006189 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6190 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6191 synchronized (this) {
6192 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6193 if (!isDebuggable) {
6194 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6195 throw new SecurityException("Process not debuggable: " + app.packageName);
6196 }
6197 }
6198 mProfileApp = processName;
6199 mProfileFile = profileFile;
6200 if (mProfileFd != null) {
6201 try {
6202 mProfileFd.close();
6203 } catch (IOException e) {
6204 }
6205 mProfileFd = null;
6206 }
6207 mProfileFd = profileFd;
6208 mProfileType = 0;
6209 mAutoStopProfiler = autoStopProfiler;
6210 }
6211 }
6212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006213 public void setAlwaysFinish(boolean enabled) {
6214 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6215 "setAlwaysFinish()");
6216
6217 Settings.System.putInt(
6218 mContext.getContentResolver(),
6219 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6220
6221 synchronized (this) {
6222 mAlwaysFinishActivities = enabled;
6223 }
6224 }
6225
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006226 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006227 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006228 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006229 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006230 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006231 }
6232 }
6233
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006234 public boolean isUserAMonkey() {
6235 // For now the fact that there is a controller implies
6236 // we have a monkey.
6237 synchronized (this) {
6238 return mController != null;
6239 }
6240 }
6241
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006242 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006243 synchronized (this) {
6244 mWatchers.register(watcher);
6245 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006246 }
6247
6248 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006249 synchronized (this) {
6250 mWatchers.unregister(watcher);
6251 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006252 }
6253
Jeff Sharkeya4620792011-05-20 15:29:23 -07006254 public void registerProcessObserver(IProcessObserver observer) {
6255 mProcessObservers.register(observer);
6256 }
6257
6258 public void unregisterProcessObserver(IProcessObserver observer) {
6259 mProcessObservers.unregister(observer);
6260 }
6261
Daniel Sandler69a48172010-06-23 16:29:36 -04006262 public void setImmersive(IBinder token, boolean immersive) {
6263 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006264 ActivityRecord r = mMainStack.isInStackLocked(token);
6265 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006266 throw new IllegalArgumentException();
6267 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006268 r.immersive = immersive;
6269 }
6270 }
6271
6272 public boolean isImmersive(IBinder token) {
6273 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006274 ActivityRecord r = mMainStack.isInStackLocked(token);
6275 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006276 throw new IllegalArgumentException();
6277 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006278 return r.immersive;
6279 }
6280 }
6281
6282 public boolean isTopActivityImmersive() {
6283 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006284 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006285 return (r != null) ? r.immersive : false;
6286 }
6287 }
6288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006289 public final void enterSafeMode() {
6290 synchronized(this) {
6291 // It only makes sense to do this before the system is ready
6292 // and started launching other packages.
6293 if (!mSystemReady) {
6294 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006295 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 } catch (RemoteException e) {
6297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006298 }
6299 }
6300 }
6301
Jeff Brownb09abc12011-01-13 21:08:27 -08006302 public final void showSafeModeOverlay() {
6303 View v = LayoutInflater.from(mContext).inflate(
6304 com.android.internal.R.layout.safe_mode, null);
6305 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6306 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6307 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6308 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6309 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6310 lp.format = v.getBackground().getOpacity();
6311 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6312 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6313 ((WindowManager)mContext.getSystemService(
6314 Context.WINDOW_SERVICE)).addView(v, lp);
6315 }
6316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 public void noteWakeupAlarm(IIntentSender sender) {
6318 if (!(sender instanceof PendingIntentRecord)) {
6319 return;
6320 }
6321 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6322 synchronized (stats) {
6323 if (mBatteryStatsService.isOnBattery()) {
6324 mBatteryStatsService.enforceCallingPermission();
6325 PendingIntentRecord rec = (PendingIntentRecord)sender;
6326 int MY_UID = Binder.getCallingUid();
6327 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6328 BatteryStatsImpl.Uid.Pkg pkg =
6329 stats.getPackageStatsLocked(uid, rec.key.packageName);
6330 pkg.incWakeupsLocked();
6331 }
6332 }
6333 }
6334
Dianne Hackborn64825172011-03-02 21:32:58 -08006335 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006336 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006337 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006338 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006339 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006340 // XXX Note: don't acquire main activity lock here, because the window
6341 // manager calls in with its locks held.
6342
6343 boolean killed = false;
6344 synchronized (mPidsSelfLocked) {
6345 int[] types = new int[pids.length];
6346 int worstType = 0;
6347 for (int i=0; i<pids.length; i++) {
6348 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6349 if (proc != null) {
6350 int type = proc.setAdj;
6351 types[i] = type;
6352 if (type > worstType) {
6353 worstType = type;
6354 }
6355 }
6356 }
6357
Dianne Hackborn64825172011-03-02 21:32:58 -08006358 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006359 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006360 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6361 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006363
6364 // If this is not a secure call, don't let it kill processes that
6365 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006366 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6367 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006368 }
6369
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006370 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006371 for (int i=0; i<pids.length; i++) {
6372 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6373 if (proc == null) {
6374 continue;
6375 }
6376 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006377 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006378 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006379 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6380 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006381 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006382 proc.killedBackground = true;
6383 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 }
6385 }
6386 }
6387 return killed;
6388 }
6389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006390 public final void startRunning(String pkg, String cls, String action,
6391 String data) {
6392 synchronized(this) {
6393 if (mStartRunning) {
6394 return;
6395 }
6396 mStartRunning = true;
6397 mTopComponent = pkg != null && cls != null
6398 ? new ComponentName(pkg, cls) : null;
6399 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6400 mTopData = data;
6401 if (!mSystemReady) {
6402 return;
6403 }
6404 }
6405
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006406 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 }
6408
6409 private void retrieveSettings() {
6410 final ContentResolver resolver = mContext.getContentResolver();
6411 String debugApp = Settings.System.getString(
6412 resolver, Settings.System.DEBUG_APP);
6413 boolean waitForDebugger = Settings.System.getInt(
6414 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6415 boolean alwaysFinishActivities = Settings.System.getInt(
6416 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6417
6418 Configuration configuration = new Configuration();
6419 Settings.System.getConfiguration(resolver, configuration);
6420
6421 synchronized (this) {
6422 mDebugApp = mOrigDebugApp = debugApp;
6423 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6424 mAlwaysFinishActivities = alwaysFinishActivities;
6425 // This happens before any activities are started, so we can
6426 // change mConfiguration in-place.
6427 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006428 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006429 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006430 }
6431 }
6432
6433 public boolean testIsSystemReady() {
6434 // no need to synchronize(this) just to read & return the value
6435 return mSystemReady;
6436 }
6437
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006438 private static File getCalledPreBootReceiversFile() {
6439 File dataDir = Environment.getDataDirectory();
6440 File systemDir = new File(dataDir, "system");
6441 File fname = new File(systemDir, "called_pre_boots.dat");
6442 return fname;
6443 }
6444
6445 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6446 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6447 File file = getCalledPreBootReceiversFile();
6448 FileInputStream fis = null;
6449 try {
6450 fis = new FileInputStream(file);
6451 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
6452 int vers = dis.readInt();
6453 String codename = dis.readUTF();
6454 if (vers == android.os.Build.VERSION.SDK_INT
6455 && codename.equals(android.os.Build.VERSION.CODENAME)) {
6456 int num = dis.readInt();
6457 while (num > 0) {
6458 num--;
6459 String pkg = dis.readUTF();
6460 String cls = dis.readUTF();
6461 lastDoneReceivers.add(new ComponentName(pkg, cls));
6462 }
6463 }
6464 } catch (FileNotFoundException e) {
6465 } catch (IOException e) {
6466 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6467 } finally {
6468 if (fis != null) {
6469 try {
6470 fis.close();
6471 } catch (IOException e) {
6472 }
6473 }
6474 }
6475 return lastDoneReceivers;
6476 }
6477
6478 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6479 File file = getCalledPreBootReceiversFile();
6480 FileOutputStream fos = null;
6481 DataOutputStream dos = null;
6482 try {
6483 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6484 fos = new FileOutputStream(file);
6485 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
6486 dos.writeInt(android.os.Build.VERSION.SDK_INT);
6487 dos.writeUTF(android.os.Build.VERSION.CODENAME);
6488 dos.writeInt(list.size());
6489 for (int i=0; i<list.size(); i++) {
6490 dos.writeUTF(list.get(i).getPackageName());
6491 dos.writeUTF(list.get(i).getClassName());
6492 }
6493 } catch (IOException e) {
6494 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6495 file.delete();
6496 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006497 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006498 if (dos != null) {
6499 try {
6500 dos.close();
6501 } catch (IOException e) {
6502 // TODO Auto-generated catch block
6503 e.printStackTrace();
6504 }
6505 }
6506 }
6507 }
6508
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006509 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006510 synchronized(this) {
6511 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006512 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 return;
6514 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006515
6516 // Check to see if there are any update receivers to run.
6517 if (!mDidUpdate) {
6518 if (mWaitingUpdate) {
6519 return;
6520 }
6521 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6522 List<ResolveInfo> ris = null;
6523 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006524 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006525 intent, null, 0);
6526 } catch (RemoteException e) {
6527 }
6528 if (ris != null) {
6529 for (int i=ris.size()-1; i>=0; i--) {
6530 if ((ris.get(i).activityInfo.applicationInfo.flags
6531 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6532 ris.remove(i);
6533 }
6534 }
6535 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006536
6537 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6538
6539 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006540 for (int i=0; i<ris.size(); i++) {
6541 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006542 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6543 if (lastDoneReceivers.contains(comp)) {
6544 ris.remove(i);
6545 i--;
6546 }
6547 }
6548
6549 for (int i=0; i<ris.size(); i++) {
6550 ActivityInfo ai = ris.get(i).activityInfo;
6551 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6552 doneReceivers.add(comp);
6553 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006554 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006555 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006556 finisher = new IIntentReceiver.Stub() {
6557 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006558 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006559 boolean sticky) {
6560 // The raw IIntentReceiver interface is called
6561 // with the AM lock held, so redispatch to
6562 // execute our code without the lock.
6563 mHandler.post(new Runnable() {
6564 public void run() {
6565 synchronized (ActivityManagerService.this) {
6566 mDidUpdate = true;
6567 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006568 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006569 systemReady(goingCallback);
6570 }
6571 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006572 }
6573 };
6574 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006575 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006576 broadcastIntentLocked(null, null, intent, null, finisher,
6577 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006578 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006579 mWaitingUpdate = true;
6580 }
6581 }
6582 }
6583 if (mWaitingUpdate) {
6584 return;
6585 }
6586 mDidUpdate = true;
6587 }
6588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006589 mSystemReady = true;
6590 if (!mStartRunning) {
6591 return;
6592 }
6593 }
6594
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006595 ArrayList<ProcessRecord> procsToKill = null;
6596 synchronized(mPidsSelfLocked) {
6597 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6598 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6599 if (!isAllowedWhileBooting(proc.info)){
6600 if (procsToKill == null) {
6601 procsToKill = new ArrayList<ProcessRecord>();
6602 }
6603 procsToKill.add(proc);
6604 }
6605 }
6606 }
6607
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006608 synchronized(this) {
6609 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006610 for (int i=procsToKill.size()-1; i>=0; i--) {
6611 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006612 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006613 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006614 }
6615 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006616
6617 // Now that we have cleaned up any update processes, we
6618 // are ready to start launching real processes and know that
6619 // we won't trample on them any more.
6620 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006621 }
6622
Joe Onorato8a9b2202010-02-26 18:56:32 -08006623 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006624 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006625 SystemClock.uptimeMillis());
6626
6627 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006628 // Make sure we have no pre-ready processes sitting around.
6629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6631 ResolveInfo ri = mContext.getPackageManager()
6632 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006633 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006634 CharSequence errorMsg = null;
6635 if (ri != null) {
6636 ActivityInfo ai = ri.activityInfo;
6637 ApplicationInfo app = ai.applicationInfo;
6638 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6639 mTopAction = Intent.ACTION_FACTORY_TEST;
6640 mTopData = null;
6641 mTopComponent = new ComponentName(app.packageName,
6642 ai.name);
6643 } else {
6644 errorMsg = mContext.getResources().getText(
6645 com.android.internal.R.string.factorytest_not_system);
6646 }
6647 } else {
6648 errorMsg = mContext.getResources().getText(
6649 com.android.internal.R.string.factorytest_no_action);
6650 }
6651 if (errorMsg != null) {
6652 mTopAction = null;
6653 mTopData = null;
6654 mTopComponent = null;
6655 Message msg = Message.obtain();
6656 msg.what = SHOW_FACTORY_ERROR_MSG;
6657 msg.getData().putCharSequence("msg", errorMsg);
6658 mHandler.sendMessage(msg);
6659 }
6660 }
6661 }
6662
6663 retrieveSettings();
6664
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006665 if (goingCallback != null) goingCallback.run();
6666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006667 synchronized (this) {
6668 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6669 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006670 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006671 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006672 if (apps != null) {
6673 int N = apps.size();
6674 int i;
6675 for (i=0; i<N; i++) {
6676 ApplicationInfo info
6677 = (ApplicationInfo)apps.get(i);
6678 if (info != null &&
6679 !info.packageName.equals("android")) {
6680 addAppLocked(info);
6681 }
6682 }
6683 }
6684 } catch (RemoteException ex) {
6685 // pm is in same process, this will never happen.
6686 }
6687 }
6688
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006689 // Start up initial activity.
6690 mBooting = true;
6691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006692 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006693 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 Message msg = Message.obtain();
6695 msg.what = SHOW_UID_ERROR_MSG;
6696 mHandler.sendMessage(msg);
6697 }
6698 } catch (RemoteException e) {
6699 }
6700
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006701 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006702 }
6703 }
6704
Dan Egnorb7f03672009-12-09 16:22:32 -08006705 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006706 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006707 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006708 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006709 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006710 startAppProblemLocked(app);
6711 app.stopFreezingAllLocked();
6712 return handleAppCrashLocked(app);
6713 }
6714
Dan Egnorb7f03672009-12-09 16:22:32 -08006715 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006716 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006717 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006718 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006719 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6720 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006721 startAppProblemLocked(app);
6722 app.stopFreezingAllLocked();
6723 }
6724
6725 /**
6726 * Generate a process error record, suitable for attachment to a ProcessRecord.
6727 *
6728 * @param app The ProcessRecord in which the error occurred.
6729 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6730 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006731 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 * @param shortMsg Short message describing the crash.
6733 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006734 * @param stackTrace Full crash stack trace, may be null.
6735 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006736 * @return Returns a fully-formed AppErrorStateInfo record.
6737 */
6738 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006739 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006740 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006741
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 report.condition = condition;
6743 report.processName = app.processName;
6744 report.pid = app.pid;
6745 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006746 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006747 report.shortMsg = shortMsg;
6748 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006749 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006750
6751 return report;
6752 }
6753
Dan Egnor42471dd2010-01-07 17:25:22 -08006754 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006755 synchronized (this) {
6756 app.crashing = false;
6757 app.crashingReport = null;
6758 app.notResponding = false;
6759 app.notRespondingReport = null;
6760 if (app.anrDialog == fromDialog) {
6761 app.anrDialog = null;
6762 }
6763 if (app.waitDialog == fromDialog) {
6764 app.waitDialog = null;
6765 }
6766 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006767 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006768 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006769 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6770 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006771 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006772 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006773 }
6774 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006775
Dan Egnorb7f03672009-12-09 16:22:32 -08006776 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 long now = SystemClock.uptimeMillis();
6778
6779 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6780 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006781 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006782 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006783 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006784 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006785 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006786 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006787 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6788 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006789 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006790 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006791 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006792 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006793 }
6794 }
6795 if (!app.persistent) {
6796 // We don't want to start this process again until the user
6797 // explicitly does so... but for persistent process, we really
6798 // need to keep it running. If a persistent process is actually
6799 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006800 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006801 app.info.processName);
6802 mBadProcesses.put(app.info.processName, app.info.uid, now);
6803 app.bad = true;
6804 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6805 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006806 // Don't let services in this process be restarted and potentially
6807 // annoy the user repeatedly. Unless it is persistent, since those
6808 // processes run critical code.
6809 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006810 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006811 return false;
6812 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006813 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006814 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006815 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006816 if (r.app == app) {
6817 // If the top running activity is from this crashing
6818 // process, then terminate it to avoid getting in a loop.
6819 Slog.w(TAG, " Force finishing activity "
6820 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006821 int index = mMainStack.indexOfTokenLocked(r);
6822 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006823 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006824 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006825 // stopped, to avoid a situation where one will get
6826 // re-start our crashing activity once it gets resumed again.
6827 index--;
6828 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006829 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006830 if (r.state == ActivityState.RESUMED
6831 || r.state == ActivityState.PAUSING
6832 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006833 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006834 Slog.w(TAG, " Force finishing activity "
6835 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006836 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006837 Activity.RESULT_CANCELED, null, "crashed");
6838 }
6839 }
6840 }
6841 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006842 }
6843
6844 // Bump up the crash count of any services currently running in the proc.
6845 if (app.services.size() != 0) {
6846 // Any services running in the application need to be placed
6847 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006848 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006849 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006850 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006851 sr.crashCount++;
6852 }
6853 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006854
6855 // If the crashing process is what we consider to be the "home process" and it has been
6856 // replaced by a third-party app, clear the package preferred activities from packages
6857 // with a home activity running in the process to prevent a repeatedly crashing app
6858 // from blocking the user to manually clear the list.
6859 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6860 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6861 Iterator it = mHomeProcess.activities.iterator();
6862 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006863 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006864 if (r.isHomeActivity) {
6865 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6866 try {
6867 ActivityThread.getPackageManager()
6868 .clearPackagePreferredActivities(r.packageName);
6869 } catch (RemoteException c) {
6870 // pm is in same process, this will never happen.
6871 }
6872 }
6873 }
6874 }
6875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006876 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6877 return true;
6878 }
6879
6880 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006881 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6882 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006883 skipCurrentReceiverLocked(app);
6884 }
6885
6886 void skipCurrentReceiverLocked(ProcessRecord app) {
6887 boolean reschedule = false;
6888 BroadcastRecord r = app.curReceiver;
6889 if (r != null) {
6890 // The current broadcast is waiting for this app's receiver
6891 // to be finished. Looks like that's not going to happen, so
6892 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006893 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006894 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6895 r.resultExtras, r.resultAbort, true);
6896 reschedule = true;
6897 }
6898 r = mPendingBroadcast;
6899 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006900 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006902 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006903 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6904 r.resultExtras, r.resultAbort, true);
6905 reschedule = true;
6906 }
6907 if (reschedule) {
6908 scheduleBroadcastsLocked();
6909 }
6910 }
6911
Dan Egnor60d87622009-12-16 16:32:58 -08006912 /**
6913 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6914 * The application process will exit immediately after this call returns.
6915 * @param app object of the crashing app, null for the system server
6916 * @param crashInfo describing the exception
6917 */
6918 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006919 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006920
6921 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6922 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006923 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006924 crashInfo.exceptionClassName,
6925 crashInfo.exceptionMessage,
6926 crashInfo.throwFileName,
6927 crashInfo.throwLineNumber);
6928
Dan Egnor42471dd2010-01-07 17:25:22 -08006929 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006930
6931 crashApplication(r, crashInfo);
6932 }
6933
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006934 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006935 IBinder app,
6936 int violationMask,
6937 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006938 ProcessRecord r = findAppProcess(app, "StrictMode");
6939 if (r == null) {
6940 return;
6941 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006942
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006943 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08006944 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006945 boolean logIt = true;
6946 synchronized (mAlreadyLoggedViolatedStacks) {
6947 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
6948 logIt = false;
6949 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006950 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006951 // the relative pain numbers, without logging all
6952 // the stack traces repeatedly. We'd want to do
6953 // likewise in the client code, which also does
6954 // dup suppression, before the Binder call.
6955 } else {
6956 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
6957 mAlreadyLoggedViolatedStacks.clear();
6958 }
6959 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
6960 }
6961 }
6962 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006963 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006964 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006965 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006966
6967 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
6968 AppErrorResult result = new AppErrorResult();
6969 synchronized (this) {
6970 final long origId = Binder.clearCallingIdentity();
6971
6972 Message msg = Message.obtain();
6973 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
6974 HashMap<String, Object> data = new HashMap<String, Object>();
6975 data.put("result", result);
6976 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07006977 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006978 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006979 msg.obj = data;
6980 mHandler.sendMessage(msg);
6981
6982 Binder.restoreCallingIdentity(origId);
6983 }
6984 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07006985 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07006986 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006987 }
6988
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006989 // Depending on the policy in effect, there could be a bunch of
6990 // these in quick succession so we try to batch these together to
6991 // minimize disk writes, number of dropbox entries, and maximize
6992 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006993 private void logStrictModeViolationToDropBox(
6994 ProcessRecord process,
6995 StrictMode.ViolationInfo info) {
6996 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07006997 return;
6998 }
6999 final boolean isSystemApp = process == null ||
7000 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7001 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7002 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7003 final DropBoxManager dbox = (DropBoxManager)
7004 mContext.getSystemService(Context.DROPBOX_SERVICE);
7005
7006 // Exit early if the dropbox isn't configured to accept this report type.
7007 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7008
7009 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007010 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007011 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7012 synchronized (sb) {
7013 bufferWasEmpty = sb.length() == 0;
7014 appendDropBoxProcessHeaders(process, sb);
7015 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7016 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007017 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7018 if (info.violationNumThisLoop != 0) {
7019 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7020 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007021 if (info.numAnimationsRunning != 0) {
7022 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7023 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007024 if (info.broadcastIntentAction != null) {
7025 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7026 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007027 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007028 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007029 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007030 if (info.numInstances != -1) {
7031 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7032 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007033 if (info.tags != null) {
7034 for (String tag : info.tags) {
7035 sb.append("Span-Tag: ").append(tag).append("\n");
7036 }
7037 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007038 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007039 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7040 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007041 }
7042 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007043
7044 // Only buffer up to ~64k. Various logging bits truncate
7045 // things at 128k.
7046 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007047 }
7048
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007049 // Flush immediately if the buffer's grown too large, or this
7050 // is a non-system app. Non-system apps are isolated with a
7051 // different tag & policy and not batched.
7052 //
7053 // Batching is useful during internal testing with
7054 // StrictMode settings turned up high. Without batching,
7055 // thousands of separate files could be created on boot.
7056 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007057 new Thread("Error dump: " + dropboxTag) {
7058 @Override
7059 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007060 String report;
7061 synchronized (sb) {
7062 report = sb.toString();
7063 sb.delete(0, sb.length());
7064 sb.trimToSize();
7065 }
7066 if (report.length() != 0) {
7067 dbox.addText(dropboxTag, report);
7068 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007069 }
7070 }.start();
7071 return;
7072 }
7073
7074 // System app batching:
7075 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007076 // An existing dropbox-writing thread is outstanding, so
7077 // we don't need to start it up. The existing thread will
7078 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007079 return;
7080 }
7081
7082 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7083 // (After this point, we shouldn't access AMS internal data structures.)
7084 new Thread("Error dump: " + dropboxTag) {
7085 @Override
7086 public void run() {
7087 // 5 second sleep to let stacks arrive and be batched together
7088 try {
7089 Thread.sleep(5000); // 5 seconds
7090 } catch (InterruptedException e) {}
7091
7092 String errorReport;
7093 synchronized (mStrictModeBuffer) {
7094 errorReport = mStrictModeBuffer.toString();
7095 if (errorReport.length() == 0) {
7096 return;
7097 }
7098 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7099 mStrictModeBuffer.trimToSize();
7100 }
7101 dbox.addText(dropboxTag, errorReport);
7102 }
7103 }.start();
7104 }
7105
Dan Egnor60d87622009-12-16 16:32:58 -08007106 /**
7107 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7108 * @param app object of the crashing app, null for the system server
7109 * @param tag reported by the caller
7110 * @param crashInfo describing the context of the error
7111 * @return true if the process should exit immediately (WTF is fatal)
7112 */
7113 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007114 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007115 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007116
7117 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7118 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007119 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007120 tag, crashInfo.exceptionMessage);
7121
Dan Egnor42471dd2010-01-07 17:25:22 -08007122 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007123
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007124 if (r != null && r.pid != Process.myPid() &&
7125 Settings.Secure.getInt(mContext.getContentResolver(),
7126 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007127 crashApplication(r, crashInfo);
7128 return true;
7129 } else {
7130 return false;
7131 }
7132 }
7133
7134 /**
7135 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7136 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7137 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007138 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007139 if (app == null) {
7140 return null;
7141 }
7142
7143 synchronized (this) {
7144 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7145 final int NA = apps.size();
7146 for (int ia=0; ia<NA; ia++) {
7147 ProcessRecord p = apps.valueAt(ia);
7148 if (p.thread != null && p.thread.asBinder() == app) {
7149 return p;
7150 }
7151 }
7152 }
7153
Dianne Hackborncb44d962011-03-10 17:02:27 -08007154 Slog.w(TAG, "Can't find mystery application for " + reason
7155 + " from pid=" + Binder.getCallingPid()
7156 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007157 return null;
7158 }
7159 }
7160
7161 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007162 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7163 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007164 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007165 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007166 // Watchdog thread ends up invoking this function (with
7167 // a null ProcessRecord) to add the stack file to dropbox.
7168 // Do not acquire a lock on this (am) in such cases, as it
7169 // could cause a potential deadlock, if and when watchdog
7170 // is invoked due to unavailability of lock on am and it
7171 // would prevent watchdog from killing system_server.
7172 if (process == null) {
7173 sb.append("Process: system_server\n");
7174 return;
7175 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007176 // Note: ProcessRecord 'process' is guarded by the service
7177 // instance. (notably process.pkgList, which could otherwise change
7178 // concurrently during execution of this method)
7179 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007180 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007181 sb.append("Process: system_server\n");
7182 } else {
7183 sb.append("Process: ").append(process.processName).append("\n");
7184 }
Dan Egnora455d192010-03-12 08:52:28 -08007185 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007186 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007187 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7188 for (String pkg : process.pkgList) {
7189 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007190 try {
Dan Egnora455d192010-03-12 08:52:28 -08007191 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7192 if (pi != null) {
7193 sb.append(" v").append(pi.versionCode);
7194 if (pi.versionName != null) {
7195 sb.append(" (").append(pi.versionName).append(")");
7196 }
7197 }
7198 } catch (RemoteException e) {
7199 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007200 }
Dan Egnora455d192010-03-12 08:52:28 -08007201 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007202 }
Dan Egnora455d192010-03-12 08:52:28 -08007203 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007204 }
7205
7206 private static String processClass(ProcessRecord process) {
7207 if (process == null || process.pid == MY_PID) {
7208 return "system_server";
7209 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7210 return "system_app";
7211 } else {
7212 return "data_app";
7213 }
7214 }
7215
7216 /**
7217 * Write a description of an error (crash, WTF, ANR) to the drop box.
7218 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7219 * @param process which caused the error, null means the system server
7220 * @param activity which triggered the error, null if unknown
7221 * @param parent activity related to the error, null if unknown
7222 * @param subject line related to the error, null if absent
7223 * @param report in long form describing the error, null if absent
7224 * @param logFile to include in the report, null if none
7225 * @param crashInfo giving an application stack trace, null if absent
7226 */
7227 public void addErrorToDropBox(String eventType,
7228 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7229 final String report, final File logFile,
7230 final ApplicationErrorReport.CrashInfo crashInfo) {
7231 // NOTE -- this must never acquire the ActivityManagerService lock,
7232 // otherwise the watchdog may be prevented from resetting the system.
7233
7234 final String dropboxTag = processClass(process) + "_" + eventType;
7235 final DropBoxManager dbox = (DropBoxManager)
7236 mContext.getSystemService(Context.DROPBOX_SERVICE);
7237
7238 // Exit early if the dropbox isn't configured to accept this report type.
7239 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7240
7241 final StringBuilder sb = new StringBuilder(1024);
7242 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007243 if (activity != null) {
7244 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7245 }
7246 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7247 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7248 }
7249 if (parent != null && parent != activity) {
7250 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7251 }
7252 if (subject != null) {
7253 sb.append("Subject: ").append(subject).append("\n");
7254 }
7255 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007256 if (Debug.isDebuggerConnected()) {
7257 sb.append("Debugger: Connected\n");
7258 }
Dan Egnora455d192010-03-12 08:52:28 -08007259 sb.append("\n");
7260
7261 // Do the rest in a worker thread to avoid blocking the caller on I/O
7262 // (After this point, we shouldn't access AMS internal data structures.)
7263 Thread worker = new Thread("Error dump: " + dropboxTag) {
7264 @Override
7265 public void run() {
7266 if (report != null) {
7267 sb.append(report);
7268 }
7269 if (logFile != null) {
7270 try {
7271 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7272 } catch (IOException e) {
7273 Slog.e(TAG, "Error reading " + logFile, e);
7274 }
7275 }
7276 if (crashInfo != null && crashInfo.stackTrace != null) {
7277 sb.append(crashInfo.stackTrace);
7278 }
7279
7280 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7281 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7282 if (lines > 0) {
7283 sb.append("\n");
7284
7285 // Merge several logcat streams, and take the last N lines
7286 InputStreamReader input = null;
7287 try {
7288 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7289 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7290 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7291
7292 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7293 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7294 input = new InputStreamReader(logcat.getInputStream());
7295
7296 int num;
7297 char[] buf = new char[8192];
7298 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7299 } catch (IOException e) {
7300 Slog.e(TAG, "Error running logcat", e);
7301 } finally {
7302 if (input != null) try { input.close(); } catch (IOException e) {}
7303 }
7304 }
7305
7306 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007307 }
Dan Egnora455d192010-03-12 08:52:28 -08007308 };
7309
7310 if (process == null || process.pid == MY_PID) {
7311 worker.run(); // We may be about to die -- need to run this synchronously
7312 } else {
7313 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007314 }
7315 }
7316
7317 /**
7318 * Bring up the "unexpected error" dialog box for a crashing app.
7319 * Deal with edge cases (intercepts from instrumented applications,
7320 * ActivityController, error intent receivers, that sort of thing).
7321 * @param r the application crashing
7322 * @param crashInfo describing the failure
7323 */
7324 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007325 long timeMillis = System.currentTimeMillis();
7326 String shortMsg = crashInfo.exceptionClassName;
7327 String longMsg = crashInfo.exceptionMessage;
7328 String stackTrace = crashInfo.stackTrace;
7329 if (shortMsg != null && longMsg != null) {
7330 longMsg = shortMsg + ": " + longMsg;
7331 } else if (shortMsg != null) {
7332 longMsg = shortMsg;
7333 }
7334
Dan Egnor60d87622009-12-16 16:32:58 -08007335 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007336 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007337 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007338 try {
7339 String name = r != null ? r.processName : null;
7340 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007341 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007342 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007343 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007344 + " at watcher's request");
7345 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007346 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007347 }
7348 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007349 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007350 }
7351 }
7352
7353 final long origId = Binder.clearCallingIdentity();
7354
7355 // If this process is running instrumentation, finish it.
7356 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007357 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007358 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007359 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7360 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007361 Bundle info = new Bundle();
7362 info.putString("shortMsg", shortMsg);
7363 info.putString("longMsg", longMsg);
7364 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7365 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007366 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007367 }
7368
Dan Egnor60d87622009-12-16 16:32:58 -08007369 // If we can't identify the process or it's already exceeded its crash quota,
7370 // quit right away without showing a crash dialog.
7371 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007372 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007373 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007374 }
7375
7376 Message msg = Message.obtain();
7377 msg.what = SHOW_ERROR_MSG;
7378 HashMap data = new HashMap();
7379 data.put("result", result);
7380 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007381 msg.obj = data;
7382 mHandler.sendMessage(msg);
7383
7384 Binder.restoreCallingIdentity(origId);
7385 }
7386
7387 int res = result.get();
7388
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007389 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007390 synchronized (this) {
7391 if (r != null) {
7392 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7393 SystemClock.uptimeMillis());
7394 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007395 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007396 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007397 }
7398 }
7399
7400 if (appErrorIntent != null) {
7401 try {
7402 mContext.startActivity(appErrorIntent);
7403 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007404 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007407 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007408
7409 Intent createAppErrorIntentLocked(ProcessRecord r,
7410 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7411 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007412 if (report == null) {
7413 return null;
7414 }
7415 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7416 result.setComponent(r.errorReportReceiver);
7417 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7418 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7419 return result;
7420 }
7421
Dan Egnorb7f03672009-12-09 16:22:32 -08007422 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7423 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007424 if (r.errorReportReceiver == null) {
7425 return null;
7426 }
7427
7428 if (!r.crashing && !r.notResponding) {
7429 return null;
7430 }
7431
Dan Egnorb7f03672009-12-09 16:22:32 -08007432 ApplicationErrorReport report = new ApplicationErrorReport();
7433 report.packageName = r.info.packageName;
7434 report.installerPackageName = r.errorReportReceiver.getPackageName();
7435 report.processName = r.processName;
7436 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007437 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007438
Dan Egnorb7f03672009-12-09 16:22:32 -08007439 if (r.crashing) {
7440 report.type = ApplicationErrorReport.TYPE_CRASH;
7441 report.crashInfo = crashInfo;
7442 } else if (r.notResponding) {
7443 report.type = ApplicationErrorReport.TYPE_ANR;
7444 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007445
Dan Egnorb7f03672009-12-09 16:22:32 -08007446 report.anrInfo.activity = r.notRespondingReport.tag;
7447 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7448 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007449 }
7450
Dan Egnorb7f03672009-12-09 16:22:32 -08007451 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007452 }
7453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007454 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7455 // assume our apps are happy - lazy create the list
7456 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7457
7458 synchronized (this) {
7459
7460 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007461 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7462 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007463 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7464 // This one's in trouble, so we'll generate a report for it
7465 // crashes are higher priority (in case there's a crash *and* an anr)
7466 ActivityManager.ProcessErrorStateInfo report = null;
7467 if (app.crashing) {
7468 report = app.crashingReport;
7469 } else if (app.notResponding) {
7470 report = app.notRespondingReport;
7471 }
7472
7473 if (report != null) {
7474 if (errList == null) {
7475 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7476 }
7477 errList.add(report);
7478 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007479 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007480 " crashing = " + app.crashing +
7481 " notResponding = " + app.notResponding);
7482 }
7483 }
7484 }
7485 }
7486
7487 return errList;
7488 }
7489
7490 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7491 // Lazy instantiation of list
7492 List<ActivityManager.RunningAppProcessInfo> runList = null;
7493 synchronized (this) {
7494 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007495 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7496 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007497 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7498 // Generate process state info for running application
7499 ActivityManager.RunningAppProcessInfo currApp =
7500 new ActivityManager.RunningAppProcessInfo(app.processName,
7501 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007502 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007503 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007504 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007505 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007506 if (app.persistent) {
7507 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007509 int adj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007510 if (adj >= ProcessList.EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007511 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007512 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007513 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007514 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7515 } else if (adj >= ProcessList.HOME_APP_ADJ) {
The Android Open Source Project4df24232009-03-05 14:34:35 -08007516 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7517 currApp.lru = 0;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007518 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007519 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007520 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007521 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007522 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007523 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007524 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007525 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7526 } else {
7527 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7528 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007529 currApp.importanceReasonCode = app.adjTypeCode;
7530 if (app.adjSource instanceof ProcessRecord) {
7531 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007532 } else if (app.adjSource instanceof ActivityRecord) {
7533 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007534 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7535 }
7536 if (app.adjTarget instanceof ComponentName) {
7537 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7538 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007539 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007540 // + " lru=" + currApp.lru);
7541 if (runList == null) {
7542 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7543 }
7544 runList.add(currApp);
7545 }
7546 }
7547 }
7548 return runList;
7549 }
7550
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007551 public List<ApplicationInfo> getRunningExternalApplications() {
7552 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7553 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7554 if (runningApps != null && runningApps.size() > 0) {
7555 Set<String> extList = new HashSet<String>();
7556 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7557 if (app.pkgList != null) {
7558 for (String pkg : app.pkgList) {
7559 extList.add(pkg);
7560 }
7561 }
7562 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007563 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007564 for (String pkg : extList) {
7565 try {
7566 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7567 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7568 retList.add(info);
7569 }
7570 } catch (RemoteException e) {
7571 }
7572 }
7573 }
7574 return retList;
7575 }
7576
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007577 @Override
7578 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007579 if (checkCallingPermission(android.Manifest.permission.DUMP)
7580 != PackageManager.PERMISSION_GRANTED) {
7581 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7582 + Binder.getCallingPid()
7583 + ", uid=" + Binder.getCallingUid()
7584 + " without permission "
7585 + android.Manifest.permission.DUMP);
7586 return;
7587 }
7588
7589 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007590 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007591
7592 int opti = 0;
7593 while (opti < args.length) {
7594 String opt = args[opti];
7595 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7596 break;
7597 }
7598 opti++;
7599 if ("-a".equals(opt)) {
7600 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007601 } else if ("-c".equals(opt)) {
7602 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007603 } else if ("-h".equals(opt)) {
7604 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007605 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007606 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007607 pw.println(" a[ctivities]: activity stack state");
7608 pw.println(" b[roadcasts]: broadcast state");
7609 pw.println(" i[ntents]: pending intent state");
7610 pw.println(" p[rocesses]: process state");
7611 pw.println(" o[om]: out of memory management");
7612 pw.println(" prov[iders]: content provider state");
7613 pw.println(" s[ervices]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007614 pw.println(" service [COMP_SPEC]: service client-side state");
7615 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
7616 pw.println(" COMP_SPEC may also be a component name (com.foo/.myApp),");
7617 pw.println(" a partial substring in a component name, an");
7618 pw.println(" ActivityRecord hex object identifier, or");
Dianne Hackbornf9302322011-06-14 18:36:14 -07007619 pw.println(" \"all\" for all objects, or");
7620 pw.println(" \"top\" for the top activity.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007621 pw.println(" -a: include all available server state.");
7622 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007623 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007624 } else {
7625 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007626 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007627 }
7628
7629 // Is the caller requesting to dump a particular piece of data?
7630 if (opti < args.length) {
7631 String cmd = args[opti];
7632 opti++;
7633 if ("activities".equals(cmd) || "a".equals(cmd)) {
7634 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007635 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007636 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007637 return;
7638 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7639 synchronized (this) {
7640 dumpBroadcastsLocked(fd, pw, args, opti, true);
7641 }
7642 return;
7643 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7644 synchronized (this) {
7645 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7646 }
7647 return;
7648 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7649 synchronized (this) {
7650 dumpProcessesLocked(fd, pw, args, opti, true);
7651 }
7652 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007653 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7654 synchronized (this) {
7655 dumpOomLocked(fd, pw, args, opti, true);
7656 }
7657 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007658 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7659 synchronized (this) {
7660 dumpProvidersLocked(fd, pw, args, opti, true);
7661 }
7662 return;
7663 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007664 String[] newArgs;
7665 String name;
7666 if (opti >= args.length) {
7667 name = null;
7668 newArgs = EMPTY_STRING_ARRAY;
7669 } else {
7670 name = args[opti];
7671 opti++;
7672 newArgs = new String[args.length - opti];
7673 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7674 }
7675 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7676 pw.println("No services match: " + name);
7677 pw.println("Use -h for help.");
7678 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007679 return;
7680 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7681 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007682 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007683 }
7684 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007685 } else {
7686 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007687 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7688 pw.println("Bad activity command, or no activities match: " + cmd);
7689 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007690 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007691 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007692 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007693 }
7694
7695 // No piece of data specified, dump everything.
7696 synchronized (this) {
7697 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007698 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007699 if (needSep) {
7700 pw.println(" ");
7701 }
7702 if (dumpAll) {
7703 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007704 }
7705 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7706 if (needSep) {
7707 pw.println(" ");
7708 }
7709 if (dumpAll) {
7710 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007711 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007712 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007713 if (needSep) {
7714 pw.println(" ");
7715 }
7716 if (dumpAll) {
7717 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007718 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007719 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007720 if (needSep) {
7721 pw.println(" ");
7722 }
7723 if (dumpAll) {
7724 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007725 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007726 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007727 if (needSep) {
7728 pw.println(" ");
7729 }
7730 if (dumpAll) {
7731 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007732 }
7733 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7734 }
7735 }
7736
7737 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007738 int opti, boolean dumpAll, boolean dumpClient) {
7739 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7740 pw.println(" Main stack:");
7741 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007742 pw.println(" ");
7743 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007744 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007745 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007746 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007747 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007748 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7749 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007750 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007751 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007752 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007753 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007754 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7755 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007756 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007757 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7758 pw.println(" ");
7759 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007760 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7761 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007762 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007763 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007764 pw.println(" ");
7765 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007766 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7767 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007768 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007769
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007770 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007771 if (mMainStack.mPausingActivity != null) {
7772 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7773 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007774 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007775 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007776 if (dumpAll) {
7777 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7778 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007780
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007781 if (mRecentTasks.size() > 0) {
7782 pw.println();
7783 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007784
7785 final int N = mRecentTasks.size();
7786 for (int i=0; i<N; i++) {
7787 TaskRecord tr = mRecentTasks.get(i);
7788 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7789 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007790 if (dumpAll) {
7791 mRecentTasks.get(i).dump(pw, " ");
7792 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007793 }
7794 }
7795
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007796 if (dumpAll) {
7797 pw.println(" ");
7798 pw.println(" mCurTask: " + mCurTask);
7799 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007800
7801 return true;
7802 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007803
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007804 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7805 int opti, boolean dumpAll) {
7806 boolean needSep = false;
7807 int numPers = 0;
7808
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007809 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7810
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007811 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007812 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7813 final int NA = procs.size();
7814 for (int ia=0; ia<NA; ia++) {
7815 if (!needSep) {
7816 pw.println(" All known processes:");
7817 needSep = true;
7818 }
7819 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007820 pw.print(r.persistent ? " *PERS*" : " *APP*");
7821 pw.print(" UID "); pw.print(procs.keyAt(ia));
7822 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007823 r.dump(pw, " ");
7824 if (r.persistent) {
7825 numPers++;
7826 }
7827 }
7828 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007829 }
7830
7831 if (mLruProcesses.size() > 0) {
7832 if (needSep) pw.println(" ");
7833 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007834 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007835 dumpProcessOomList(pw, this, mLruProcesses, " ",
7836 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007837 needSep = true;
7838 }
7839
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007840 if (dumpAll) {
7841 synchronized (mPidsSelfLocked) {
7842 if (mPidsSelfLocked.size() > 0) {
7843 if (needSep) pw.println(" ");
7844 needSep = true;
7845 pw.println(" PID mappings:");
7846 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7847 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7848 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007850 }
7851 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007852 }
7853
7854 if (mForegroundProcesses.size() > 0) {
7855 if (needSep) pw.println(" ");
7856 needSep = true;
7857 pw.println(" Foreground Processes:");
7858 for (int i=0; i<mForegroundProcesses.size(); i++) {
7859 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7860 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007861 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007862 }
7863
7864 if (mPersistentStartingProcesses.size() > 0) {
7865 if (needSep) pw.println(" ");
7866 needSep = true;
7867 pw.println(" Persisent processes that are starting:");
7868 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007869 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007870 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007871
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007872 if (mRemovedProcesses.size() > 0) {
7873 if (needSep) pw.println(" ");
7874 needSep = true;
7875 pw.println(" Processes that are being removed:");
7876 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007877 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007878 }
7879
7880 if (mProcessesOnHold.size() > 0) {
7881 if (needSep) pw.println(" ");
7882 needSep = true;
7883 pw.println(" Processes that are on old until the system is ready:");
7884 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007885 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007886 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007887
Dianne Hackborn287952c2010-09-22 22:34:31 -07007888 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007889
7890 if (mProcessCrashTimes.getMap().size() > 0) {
7891 if (needSep) pw.println(" ");
7892 needSep = true;
7893 pw.println(" Time since processes crashed:");
7894 long now = SystemClock.uptimeMillis();
7895 for (Map.Entry<String, SparseArray<Long>> procs
7896 : mProcessCrashTimes.getMap().entrySet()) {
7897 SparseArray<Long> uids = procs.getValue();
7898 final int N = uids.size();
7899 for (int i=0; i<N; i++) {
7900 pw.print(" Process "); pw.print(procs.getKey());
7901 pw.print(" uid "); pw.print(uids.keyAt(i));
7902 pw.print(": last crashed ");
7903 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007904 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007905 }
7906 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007908
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007909 if (mBadProcesses.getMap().size() > 0) {
7910 if (needSep) pw.println(" ");
7911 needSep = true;
7912 pw.println(" Bad processes:");
7913 for (Map.Entry<String, SparseArray<Long>> procs
7914 : mBadProcesses.getMap().entrySet()) {
7915 SparseArray<Long> uids = procs.getValue();
7916 final int N = uids.size();
7917 for (int i=0; i<N; i++) {
7918 pw.print(" Bad process "); pw.print(procs.getKey());
7919 pw.print(" uid "); pw.print(uids.keyAt(i));
7920 pw.print(": crashed at time ");
7921 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007922 }
7923 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007924 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007926 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007927 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007928 if (mHeavyWeightProcess != null) {
7929 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7930 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007931 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007932 if (dumpAll) {
7933 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007934 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007935 pw.println(" mScreenCompatPackages:");
7936 for (Map.Entry<String, Integer> entry
7937 : mCompatModePackages.getPackages().entrySet()) {
7938 String pkg = entry.getKey();
7939 int mode = entry.getValue();
7940 pw.print(" "); pw.print(pkg); pw.print(": ");
7941 pw.print(mode); pw.println();
7942 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07007943 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007944 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007945 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
7946 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
7947 || mOrigWaitForDebugger) {
7948 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
7949 + " mDebugTransient=" + mDebugTransient
7950 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
7951 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007952 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
7953 || mProfileFd != null) {
7954 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
7955 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
7956 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
7957 + mAutoStopProfiler);
7958 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007959 if (mAlwaysFinishActivities || mController != null) {
7960 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
7961 + " mController=" + mController);
7962 }
7963 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007964 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007965 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07007966 + " mProcessesReady=" + mProcessesReady
7967 + " mSystemReady=" + mSystemReady);
7968 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007969 + " mBooted=" + mBooted
7970 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007971 pw.print(" mLastPowerCheckRealtime=");
7972 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
7973 pw.println("");
7974 pw.print(" mLastPowerCheckUptime=");
7975 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
7976 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007977 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
7978 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07007979 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007980 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007981
7982 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007983 }
7984
Dianne Hackborn287952c2010-09-22 22:34:31 -07007985 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
7986 int opti, boolean needSep, boolean dumpAll) {
7987 if (mProcessesToGc.size() > 0) {
7988 if (needSep) pw.println(" ");
7989 needSep = true;
7990 pw.println(" Processes that are waiting to GC:");
7991 long now = SystemClock.uptimeMillis();
7992 for (int i=0; i<mProcessesToGc.size(); i++) {
7993 ProcessRecord proc = mProcessesToGc.get(i);
7994 pw.print(" Process "); pw.println(proc);
7995 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
7996 pw.print(", last gced=");
7997 pw.print(now-proc.lastRequestedGc);
7998 pw.print(" ms ago, last lowMem=");
7999 pw.print(now-proc.lastLowMemory);
8000 pw.println(" ms ago");
8001
8002 }
8003 }
8004 return needSep;
8005 }
8006
8007 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8008 int opti, boolean dumpAll) {
8009 boolean needSep = false;
8010
8011 if (mLruProcesses.size() > 0) {
8012 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8013
8014 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8015 @Override
8016 public int compare(ProcessRecord object1, ProcessRecord object2) {
8017 if (object1.setAdj != object2.setAdj) {
8018 return object1.setAdj > object2.setAdj ? -1 : 1;
8019 }
8020 if (object1.setSchedGroup != object2.setSchedGroup) {
8021 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8022 }
8023 if (object1.keeping != object2.keeping) {
8024 return object1.keeping ? -1 : 1;
8025 }
8026 if (object1.pid != object2.pid) {
8027 return object1.pid > object2.pid ? -1 : 1;
8028 }
8029 return 0;
8030 }
8031 };
8032
8033 Collections.sort(procs, comparator);
8034
8035 if (needSep) pw.println(" ");
8036 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008037 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008038 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8039 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8040 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8041 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8042 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8043 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8044 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8045 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8046 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8047 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8048 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008049
8050 if (needSep) pw.println(" ");
8051 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008052 pw.println(" Process OOM control:");
8053 dumpProcessOomList(pw, this, procs, " ",
8054 "Proc", "PERS", true);
8055 needSep = true;
8056 }
8057
8058 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8059
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008060 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008061 pw.println(" mHomeProcess: " + mHomeProcess);
8062 if (mHeavyWeightProcess != null) {
8063 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8064 }
8065
8066 return true;
8067 }
8068
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008069 /**
8070 * There are three ways to call this:
8071 * - no service specified: dump all the services
8072 * - a flattened component name that matched an existing service was specified as the
8073 * first arg: dump that one service
8074 * - the first arg isn't the flattened component name of an existing service:
8075 * dump all services whose component contains the first arg as a substring
8076 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008077 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8078 int opti, boolean dumpAll) {
8079 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008080
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008081 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008082 synchronized (this) {
8083 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008084 services.add(r1);
8085 }
8086 }
8087 } else {
8088 ComponentName componentName = name != null
8089 ? ComponentName.unflattenFromString(name) : null;
8090 int objectId = 0;
8091 if (componentName == null) {
8092 // Not a '/' separated full component name; maybe an object ID?
8093 try {
8094 objectId = Integer.parseInt(name, 16);
8095 name = null;
8096 componentName = null;
8097 } catch (RuntimeException e) {
8098 }
8099 }
8100
8101 synchronized (this) {
8102 for (ServiceRecord r1 : mServices.values()) {
8103 if (componentName != null) {
8104 if (r1.name.equals(componentName)) {
8105 services.add(r1);
8106 }
8107 } else if (name != null) {
8108 if (r1.name.flattenToString().contains(name)) {
8109 services.add(r1);
8110 }
8111 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008112 services.add(r1);
8113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008114 }
8115 }
8116 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008117
8118 if (services.size() <= 0) {
8119 return false;
8120 }
8121
8122 boolean needSep = false;
8123 for (int i=0; i<services.size(); i++) {
8124 if (needSep) {
8125 pw.println();
8126 }
8127 needSep = true;
8128 dumpService("", fd, pw, services.get(i), args, dumpAll);
8129 }
8130 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 }
8132
8133 /**
8134 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8135 * there is a thread associated with the service.
8136 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008137 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8138 final ServiceRecord r, String[] args, boolean dumpAll) {
8139 String innerPrefix = prefix + " ";
8140 synchronized (this) {
8141 pw.print(prefix); pw.print("SERVICE ");
8142 pw.print(r.shortName); pw.print(" ");
8143 pw.print(Integer.toHexString(System.identityHashCode(r)));
8144 pw.print(" pid=");
8145 if (r.app != null) pw.println(r.app.pid);
8146 else pw.println("(not running)");
8147 if (dumpAll) {
8148 r.dump(pw, innerPrefix);
8149 }
8150 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008151 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008152 pw.print(prefix); pw.println(" Client:");
8153 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008154 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008155 TransferPipe tp = new TransferPipe();
8156 try {
8157 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8158 tp.setBufferPrefix(prefix + " ");
8159 tp.go(fd);
8160 } finally {
8161 tp.kill();
8162 }
8163 } catch (IOException e) {
8164 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008165 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008166 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008167 }
8168 }
8169 }
8170
Dianne Hackborn625ac272010-09-17 18:29:22 -07008171 /**
8172 * There are three things that cmd can be:
8173 * - a flattened component name that matched an existing activity
8174 * - the cmd arg isn't the flattened component name of an existing activity:
8175 * dump all activity whose component contains the cmd as a substring
8176 * - A hex number of the ActivityRecord object instance.
8177 */
8178 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8179 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008180 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008181
8182 if ("all".equals(name)) {
8183 synchronized (this) {
8184 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008185 activities.add(r1);
8186 }
8187 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008188 } else if ("top".equals(name)) {
8189 synchronized (this) {
8190 final int N = mMainStack.mHistory.size();
8191 if (N > 0) {
8192 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8193 }
8194 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008195 } else {
8196 ComponentName componentName = ComponentName.unflattenFromString(name);
8197 int objectId = 0;
8198 if (componentName == null) {
8199 // Not a '/' separated full component name; maybe an object ID?
8200 try {
8201 objectId = Integer.parseInt(name, 16);
8202 name = null;
8203 componentName = null;
8204 } catch (RuntimeException e) {
8205 }
8206 }
8207
8208 synchronized (this) {
8209 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
8210 if (componentName != null) {
8211 if (r1.intent.getComponent().equals(componentName)) {
8212 activities.add(r1);
8213 }
8214 } else if (name != null) {
8215 if (r1.intent.getComponent().flattenToString().contains(name)) {
8216 activities.add(r1);
8217 }
8218 } else if (System.identityHashCode(r1) == objectId) {
8219 activities.add(r1);
8220 }
8221 }
8222 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008223 }
8224
8225 if (activities.size() <= 0) {
8226 return false;
8227 }
8228
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008229 String[] newArgs = new String[args.length - opti];
8230 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8231
Dianne Hackborn30d71892010-12-11 10:37:55 -08008232 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008233 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008234 for (int i=activities.size()-1; i>=0; i--) {
8235 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008236 if (needSep) {
8237 pw.println();
8238 }
8239 needSep = true;
8240 synchronized (this) {
8241 if (lastTask != r.task) {
8242 lastTask = r.task;
8243 pw.print("TASK "); pw.print(lastTask.affinity);
8244 pw.print(" id="); pw.println(lastTask.taskId);
8245 if (dumpAll) {
8246 lastTask.dump(pw, " ");
8247 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008248 }
8249 }
8250 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008251 }
8252 return true;
8253 }
8254
8255 /**
8256 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8257 * there is a thread associated with the activity.
8258 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008259 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008260 final ActivityRecord r, String[] args, boolean dumpAll) {
8261 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008262 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008263 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8264 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8265 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008266 if (r.app != null) pw.println(r.app.pid);
8267 else pw.println("(not running)");
8268 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008269 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008270 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008271 }
8272 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008273 // flush anything that is already in the PrintWriter since the thread is going
8274 // to write to the file descriptor directly
8275 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008276 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008277 TransferPipe tp = new TransferPipe();
8278 try {
8279 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8280 innerPrefix, args);
8281 tp.go(fd);
8282 } finally {
8283 tp.kill();
8284 }
8285 } catch (IOException e) {
8286 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008287 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008288 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008289 }
8290 }
8291 }
8292
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008293 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8294 int opti, boolean dumpAll) {
8295 boolean needSep = false;
8296
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008297 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008298 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008299 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300 pw.println(" Registered Receivers:");
8301 Iterator it = mRegisteredReceivers.values().iterator();
8302 while (it.hasNext()) {
8303 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008304 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008305 r.dump(pw, " ");
8306 }
8307 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008308
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008309 pw.println();
8310 pw.println(" Receiver Resolver Table:");
8311 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008312 needSep = true;
8313 }
8314
8315 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8316 || mPendingBroadcast != null) {
8317 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008318 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008319 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008320 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008321 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8322 pw.println(" Broadcast #" + i + ":");
8323 mParallelBroadcasts.get(i).dump(pw, " ");
8324 }
8325 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008326 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008327 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008328 }
8329 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8330 pw.println(" Serialized Broadcast #" + i + ":");
8331 mOrderedBroadcasts.get(i).dump(pw, " ");
8332 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008333 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008334 pw.println(" Pending broadcast:");
8335 if (mPendingBroadcast != null) {
8336 mPendingBroadcast.dump(pw, " ");
8337 } else {
8338 pw.println(" (null)");
8339 }
8340 needSep = true;
8341 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008342
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008343 if (needSep) {
8344 pw.println();
8345 }
8346 pw.println(" Historical broadcasts:");
8347 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8348 BroadcastRecord r = mBroadcastHistory[i];
8349 if (r == null) {
8350 break;
8351 }
8352 if (dumpAll) {
8353 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8354 r.dump(pw, " ");
8355 } else {
8356 if (i >= 50) {
8357 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008358 break;
8359 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008360 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008361 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008362 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008363 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008364
8365 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008366 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008367 pw.println(" Sticky broadcasts:");
8368 StringBuilder sb = new StringBuilder(128);
8369 for (Map.Entry<String, ArrayList<Intent>> ent
8370 : mStickyBroadcasts.entrySet()) {
8371 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008372 if (dumpAll) {
8373 pw.println(":");
8374 ArrayList<Intent> intents = ent.getValue();
8375 final int N = intents.size();
8376 for (int i=0; i<N; i++) {
8377 sb.setLength(0);
8378 sb.append(" Intent: ");
8379 intents.get(i).toShortString(sb, true, false);
8380 pw.println(sb.toString());
8381 Bundle bundle = intents.get(i).getExtras();
8382 if (bundle != null) {
8383 pw.print(" ");
8384 pw.println(bundle.toString());
8385 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008386 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008387 } else {
8388 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008389 }
8390 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008391 needSep = true;
8392 }
8393
8394 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008395 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008396 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008397 pw.println(" mHandler:");
8398 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008399 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008400 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008401
8402 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008403 }
8404
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008405 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008406 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008407 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008408
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008409 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8410 if (mServices.size() > 0) {
8411 pw.println(" Active services:");
8412 long nowReal = SystemClock.elapsedRealtime();
8413 Iterator<ServiceRecord> it = mServices.values().iterator();
8414 needSep = false;
8415 while (it.hasNext()) {
8416 ServiceRecord r = it.next();
8417 if (needSep) {
8418 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008419 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008420 pw.print(" * "); pw.println(r);
8421 if (dumpAll) {
8422 r.dump(pw, " ");
8423 needSep = true;
8424 } else {
8425 pw.print(" app="); pw.println(r.app);
8426 pw.print(" created=");
8427 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8428 pw.print(" started="); pw.print(r.startRequested);
8429 pw.print(" connections="); pw.println(r.connections.size());
8430 }
8431 if (dumpClient && r.app != null && r.app.thread != null) {
8432 pw.println(" Client:");
8433 pw.flush();
8434 try {
8435 TransferPipe tp = new TransferPipe();
8436 try {
8437 r.app.thread.dumpService(
8438 tp.getWriteFd().getFileDescriptor(), r, args);
8439 tp.setBufferPrefix(" ");
8440 // Short timeout, since blocking here can
8441 // deadlock with the application.
8442 tp.go(fd, 2000);
8443 } finally {
8444 tp.kill();
8445 }
8446 } catch (IOException e) {
8447 pw.println(" Failure while dumping the service: " + e);
8448 } catch (RemoteException e) {
8449 pw.println(" Got a RemoteException while dumping the service");
8450 }
8451 needSep = true;
8452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008453 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008454 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008455 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008456
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008457 if (mPendingServices.size() > 0) {
8458 if (needSep) pw.println(" ");
8459 pw.println(" Pending services:");
8460 for (int i=0; i<mPendingServices.size(); i++) {
8461 ServiceRecord r = mPendingServices.get(i);
8462 pw.print(" * Pending "); pw.println(r);
8463 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008464 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008465 needSep = true;
8466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008467
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008468 if (mRestartingServices.size() > 0) {
8469 if (needSep) pw.println(" ");
8470 pw.println(" Restarting services:");
8471 for (int i=0; i<mRestartingServices.size(); i++) {
8472 ServiceRecord r = mRestartingServices.get(i);
8473 pw.print(" * Restarting "); pw.println(r);
8474 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008475 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008476 needSep = true;
8477 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008478
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008479 if (mStoppingServices.size() > 0) {
8480 if (needSep) pw.println(" ");
8481 pw.println(" Stopping services:");
8482 for (int i=0; i<mStoppingServices.size(); i++) {
8483 ServiceRecord r = mStoppingServices.get(i);
8484 pw.print(" * Stopping "); pw.println(r);
8485 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008486 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008487 needSep = true;
8488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008489
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008490 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008491 if (mServiceConnections.size() > 0) {
8492 if (needSep) pw.println(" ");
8493 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008494 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008495 = mServiceConnections.values().iterator();
8496 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008497 ArrayList<ConnectionRecord> r = it.next();
8498 for (int i=0; i<r.size(); i++) {
8499 pw.print(" * "); pw.println(r.get(i));
8500 r.get(i).dump(pw, " ");
8501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008502 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008503 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008504 }
8505 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008506
8507 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508 }
8509
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008510 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8511 int opti, boolean dumpAll) {
8512 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008514 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8515 if (mProvidersByClass.size() > 0) {
8516 if (needSep) pw.println(" ");
8517 pw.println(" Published content providers (by class):");
8518 Iterator<Map.Entry<String, ContentProviderRecord>> it
8519 = mProvidersByClass.entrySet().iterator();
8520 while (it.hasNext()) {
8521 Map.Entry<String, ContentProviderRecord> e = it.next();
8522 ContentProviderRecord r = e.getValue();
8523 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008524 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008525 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008526 } else {
8527 pw.print(" * "); pw.print(r.name.toShortString());
8528 if (r.app != null) {
8529 pw.println(":");
8530 pw.print(" "); pw.println(r.app);
8531 } else {
8532 pw.println();
8533 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008534 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008535 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008536 needSep = true;
8537 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008538
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008539 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008540 if (mProvidersByName.size() > 0) {
8541 pw.println(" ");
8542 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008543 Iterator<Map.Entry<String, ContentProviderRecord>> it
8544 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008545 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008546 Map.Entry<String, ContentProviderRecord> e = it.next();
8547 ContentProviderRecord r = e.getValue();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008548 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8549 pw.println(r);
8550 }
8551 needSep = true;
8552 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008553 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008554
8555 if (mLaunchingProviders.size() > 0) {
8556 if (needSep) pw.println(" ");
8557 pw.println(" Launching content providers:");
8558 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8559 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8560 pw.println(mLaunchingProviders.get(i));
8561 }
8562 needSep = true;
8563 }
8564
8565 if (mGrantedUriPermissions.size() > 0) {
8566 pw.println();
8567 pw.println("Granted Uri Permissions:");
8568 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8569 int uid = mGrantedUriPermissions.keyAt(i);
8570 HashMap<Uri, UriPermission> perms
8571 = mGrantedUriPermissions.valueAt(i);
8572 pw.print(" * UID "); pw.print(uid);
8573 pw.println(" holds:");
8574 for (UriPermission perm : perms.values()) {
8575 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008576 if (dumpAll) {
8577 perm.dump(pw, " ");
8578 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008579 }
8580 }
8581 needSep = true;
8582 }
8583
8584 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585 }
8586
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008587 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8588 int opti, boolean dumpAll) {
8589 boolean needSep = false;
8590
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008591 if (this.mIntentSenderRecords.size() > 0) {
8592 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8593 Iterator<WeakReference<PendingIntentRecord>> it
8594 = mIntentSenderRecords.values().iterator();
8595 while (it.hasNext()) {
8596 WeakReference<PendingIntentRecord> ref = it.next();
8597 PendingIntentRecord rec = ref != null ? ref.get(): null;
8598 needSep = true;
8599 if (rec != null) {
8600 pw.print(" * "); pw.println(rec);
8601 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008602 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008603 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008604 } else {
8605 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008606 }
8607 }
8608 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008609
8610 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008611 }
8612
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008613 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8614 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008615 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008616 boolean needNL = false;
8617 final String innerPrefix = prefix + " ";
8618 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008619 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008620 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008621 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008622 if (needNL) {
8623 pw.println(" ");
8624 needNL = false;
8625 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008626 if (lastTask != r.task) {
8627 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008628 pw.print(prefix);
8629 pw.print(full ? "* " : " ");
8630 pw.println(lastTask);
8631 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008632 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008633 } else if (complete) {
8634 // Complete + brief == give a summary. Isn't that obvious?!?
8635 if (lastTask.intent != null) {
8636 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8637 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008639 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008640 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8641 pw.print(" #"); pw.print(i); pw.print(": ");
8642 pw.println(r);
8643 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008644 r.dump(pw, innerPrefix);
8645 } else if (complete) {
8646 // Complete + brief == give a summary. Isn't that obvious?!?
8647 pw.print(innerPrefix); pw.println(r.intent);
8648 if (r.app != null) {
8649 pw.print(innerPrefix); pw.println(r.app);
8650 }
8651 }
8652 if (client && r.app != null && r.app.thread != null) {
8653 // flush anything that is already in the PrintWriter since the thread is going
8654 // to write to the file descriptor directly
8655 pw.flush();
8656 try {
8657 TransferPipe tp = new TransferPipe();
8658 try {
8659 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8660 innerPrefix, args);
8661 // Short timeout, since blocking here can
8662 // deadlock with the application.
8663 tp.go(fd, 2000);
8664 } finally {
8665 tp.kill();
8666 }
8667 } catch (IOException e) {
8668 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8669 } catch (RemoteException e) {
8670 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8671 }
8672 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008673 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008674 }
8675 }
8676
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008677 private static String buildOomTag(String prefix, String space, int val, int base) {
8678 if (val == base) {
8679 if (space == null) return prefix;
8680 return prefix + " ";
8681 }
8682 return prefix + "+" + Integer.toString(val-base);
8683 }
8684
8685 private static final int dumpProcessList(PrintWriter pw,
8686 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008687 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008688 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008689 final int N = list.size()-1;
8690 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008691 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008692 pw.println(String.format("%s%s #%2d: %s",
8693 prefix, (r.persistent ? persistentLabel : normalLabel),
8694 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008695 if (r.persistent) {
8696 numPers++;
8697 }
8698 }
8699 return numPers;
8700 }
8701
Dianne Hackborn287952c2010-09-22 22:34:31 -07008702 private static final void dumpProcessOomList(PrintWriter pw,
8703 ActivityManagerService service, List<ProcessRecord> list,
8704 String prefix, String normalLabel, String persistentLabel,
8705 boolean inclDetails) {
8706
8707 final long curRealtime = SystemClock.elapsedRealtime();
8708 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8709 final long curUptime = SystemClock.uptimeMillis();
8710 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8711
8712 final int N = list.size()-1;
8713 for (int i=N; i>=0; i--) {
8714 ProcessRecord r = list.get(i);
8715 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008716 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8717 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8718 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8719 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8720 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8721 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8722 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8723 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8724 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8725 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8726 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8727 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8728 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8729 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8730 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8731 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8732 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8733 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8734 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8735 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8736 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8737 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008738 } else {
8739 oomAdj = Integer.toString(r.setAdj);
8740 }
8741 String schedGroup;
8742 switch (r.setSchedGroup) {
8743 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8744 schedGroup = "B";
8745 break;
8746 case Process.THREAD_GROUP_DEFAULT:
8747 schedGroup = "F";
8748 break;
8749 default:
8750 schedGroup = Integer.toString(r.setSchedGroup);
8751 break;
8752 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008753 String foreground;
8754 if (r.foregroundActivities) {
8755 foreground = "A";
8756 } else if (r.foregroundServices) {
8757 foreground = "S";
8758 } else {
8759 foreground = " ";
8760 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008761 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008762 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008763 N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
8764 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008765 if (r.adjSource != null || r.adjTarget != null) {
8766 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008767 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008768 if (r.adjTarget instanceof ComponentName) {
8769 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8770 } else if (r.adjTarget != null) {
8771 pw.print(r.adjTarget.toString());
8772 } else {
8773 pw.print("{null}");
8774 }
8775 pw.print("<=");
8776 if (r.adjSource instanceof ProcessRecord) {
8777 pw.print("Proc{");
8778 pw.print(((ProcessRecord)r.adjSource).toShortString());
8779 pw.println("}");
8780 } else if (r.adjSource != null) {
8781 pw.println(r.adjSource.toString());
8782 } else {
8783 pw.println("{null}");
8784 }
8785 }
8786 if (inclDetails) {
8787 pw.print(prefix);
8788 pw.print(" ");
8789 pw.print("oom: max="); pw.print(r.maxAdj);
8790 pw.print(" hidden="); pw.print(r.hiddenAdj);
8791 pw.print(" curRaw="); pw.print(r.curRawAdj);
8792 pw.print(" setRaw="); pw.print(r.setRawAdj);
8793 pw.print(" cur="); pw.print(r.curAdj);
8794 pw.print(" set="); pw.println(r.setAdj);
8795 pw.print(prefix);
8796 pw.print(" ");
8797 pw.print("keeping="); pw.print(r.keeping);
8798 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008799 pw.print(" empty="); pw.print(r.empty);
8800 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008801
8802 if (!r.keeping) {
8803 if (r.lastWakeTime != 0) {
8804 long wtime;
8805 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8806 synchronized (stats) {
8807 wtime = stats.getProcessWakeTime(r.info.uid,
8808 r.pid, curRealtime);
8809 }
8810 long timeUsed = wtime - r.lastWakeTime;
8811 pw.print(prefix);
8812 pw.print(" ");
8813 pw.print("keep awake over ");
8814 TimeUtils.formatDuration(realtimeSince, pw);
8815 pw.print(" used ");
8816 TimeUtils.formatDuration(timeUsed, pw);
8817 pw.print(" (");
8818 pw.print((timeUsed*100)/realtimeSince);
8819 pw.println("%)");
8820 }
8821 if (r.lastCpuTime != 0) {
8822 long timeUsed = r.curCpuTime - r.lastCpuTime;
8823 pw.print(prefix);
8824 pw.print(" ");
8825 pw.print("run cpu over ");
8826 TimeUtils.formatDuration(uptimeSince, pw);
8827 pw.print(" used ");
8828 TimeUtils.formatDuration(timeUsed, pw);
8829 pw.print(" (");
8830 pw.print((timeUsed*100)/uptimeSince);
8831 pw.println("%)");
8832 }
8833 }
8834 }
8835 }
8836 }
8837
Dianne Hackbornb437e092011-08-05 17:50:29 -07008838 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008839 ArrayList<ProcessRecord> procs;
8840 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008841 if (args != null && args.length > start
8842 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008843 procs = new ArrayList<ProcessRecord>();
8844 int pid = -1;
8845 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008846 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008847 } catch (NumberFormatException e) {
8848
8849 }
8850 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8851 ProcessRecord proc = mLruProcesses.get(i);
8852 if (proc.pid == pid) {
8853 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07008854 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008855 procs.add(proc);
8856 }
8857 }
8858 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008859 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008860 return null;
8861 }
8862 } else {
8863 procs = new ArrayList<ProcessRecord>(mLruProcesses);
8864 }
8865 }
8866 return procs;
8867 }
8868
8869 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
8870 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008871 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008872 if (procs == null) {
8873 return;
8874 }
8875
8876 long uptime = SystemClock.uptimeMillis();
8877 long realtime = SystemClock.elapsedRealtime();
8878 pw.println("Applications Graphics Acceleration Info:");
8879 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8880
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008881 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
8882 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008883 if (r.thread != null) {
8884 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
8885 pw.flush();
8886 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008887 TransferPipe tp = new TransferPipe();
8888 try {
8889 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
8890 tp.go(fd);
8891 } finally {
8892 tp.kill();
8893 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008894 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008895 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008896 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07008897 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008898 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07008899 pw.flush();
8900 }
8901 }
8902 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07008903 }
8904
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008905 final static class MemItem {
8906 final String label;
8907 final long pss;
8908
8909 public MemItem(String _label, long _pss) {
8910 label = _label;
8911 pss = _pss;
8912 }
8913 }
8914
Dianne Hackbornb437e092011-08-05 17:50:29 -07008915 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
8916 boolean sort) {
8917 if (sort) {
8918 Collections.sort(items, new Comparator<MemItem>() {
8919 @Override
8920 public int compare(MemItem lhs, MemItem rhs) {
8921 if (lhs.pss < rhs.pss) {
8922 return 1;
8923 } else if (lhs.pss > rhs.pss) {
8924 return -1;
8925 }
8926 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008927 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07008928 });
8929 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008930
8931 for (int i=0; i<items.size(); i++) {
8932 MemItem mi = items.get(i);
8933 pw.print(prefix); pw.printf("%8d Kb: ", mi.pss); pw.println(mi.label);
8934 }
8935 }
8936
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008937 final void dumpApplicationMemoryUsage(FileDescriptor fd,
8938 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07008939 boolean dumpAll = false;
8940
8941 int opti = 0;
8942 while (opti < args.length) {
8943 String opt = args[opti];
8944 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8945 break;
8946 }
8947 opti++;
8948 if ("-a".equals(opt)) {
8949 dumpAll = true;
8950 } else if ("-h".equals(opt)) {
8951 pw.println("meminfo dump options: [-a] [process]");
8952 pw.println(" -a: include all available information for each process.");
8953 pw.println("If [process] is specified it can be the name or ");
8954 pw.println("pid of a specific process to dump.");
8955 return;
8956 } else {
8957 pw.println("Unknown argument: " + opt + "; use -h for help");
8958 }
8959 }
8960
8961 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008962 if (procs == null) {
8963 return;
8964 }
8965
Dianne Hackborn6447ca32009-04-07 19:50:08 -07008966 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008967 long uptime = SystemClock.uptimeMillis();
8968 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07008969
8970 if (procs.size() == 1 || isCheckinRequest) {
8971 dumpAll = true;
8972 }
8973
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008974 if (isCheckinRequest) {
8975 // short checkin version
8976 pw.println(uptime + "," + realtime);
8977 pw.flush();
8978 } else {
8979 pw.println("Applications Memory Usage (kB):");
8980 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
8981 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008982
Dianne Hackbornb437e092011-08-05 17:50:29 -07008983 String[] innerArgs = new String[args.length-opti];
8984 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
8985
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07008986 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
8987 long nativePss=0, dalvikPss=0, otherPss=0;
8988 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
8989
Dianne Hackbornb437e092011-08-05 17:50:29 -07008990 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07008991 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
8992 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
8993 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07008994 };
8995 final String[] oomLabel = new String[] {
8996 "System", "Persistent", "Foreground",
8997 "Visible", "Perceptible", "Heavy Weight",
8998 "Backup", "Services", "Home", "Background"
8999 };
9000 long oomPss[] = new long[oomLabel.length];
9001
9002 long totalPss = 0;
9003
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009004 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9005 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009006 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009007 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009008 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9009 pw.flush();
9010 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009011 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009012 if (dumpAll) {
9013 try {
9014 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9015 } catch (RemoteException e) {
9016 if (!isCheckinRequest) {
9017 pw.println("Got RemoteException!");
9018 pw.flush();
9019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009020 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009021 } else {
9022 mi = new Debug.MemoryInfo();
9023 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009024 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009025
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009026 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009027 long myTotalPss = mi.getTotalPss();
9028 totalPss += myTotalPss;
9029 procMems.add(new MemItem(r.processName + " (pid " + r.pid + ")", myTotalPss));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009030
9031 nativePss += mi.nativePss;
9032 dalvikPss += mi.dalvikPss;
9033 otherPss += mi.otherPss;
9034 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9035 long mem = mi.getOtherPss(j);
9036 miscPss[j] += mem;
9037 otherPss -= mem;
9038 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009039
9040 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9041 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9042 oomPss[oomIndex] += myTotalPss;
9043 break;
9044 }
9045 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009047 }
9048 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009049
9050 if (!isCheckinRequest && procs.size() > 1) {
9051 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9052
9053 catMems.add(new MemItem("Native", nativePss));
9054 catMems.add(new MemItem("Dalvik", dalvikPss));
9055 catMems.add(new MemItem("Unknown", otherPss));
9056 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9057 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9058 }
9059
Dianne Hackbornb437e092011-08-05 17:50:29 -07009060 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9061 for (int j=0; j<oomPss.length; j++) {
9062 if (oomPss[j] != 0) {
9063 oomMems.add(new MemItem(oomLabel[j], oomPss[j]));
9064 }
9065 }
9066
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009067 pw.println();
9068 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009069 dumpMemItems(pw, " ", procMems, true);
9070 pw.println();
9071 pw.println("Total PSS by OOM adjustment:");
9072 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009073 pw.println();
9074 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009075 dumpMemItems(pw, " ", catMems, true);
9076 pw.println();
9077 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009078 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009079 }
9080
9081 /**
9082 * Searches array of arguments for the specified string
9083 * @param args array of argument strings
9084 * @param value value to search for
9085 * @return true if the value is contained in the array
9086 */
9087 private static boolean scanArgs(String[] args, String value) {
9088 if (args != null) {
9089 for (String arg : args) {
9090 if (value.equals(arg)) {
9091 return true;
9092 }
9093 }
9094 }
9095 return false;
9096 }
9097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009098 private final void killServicesLocked(ProcessRecord app,
9099 boolean allowRestart) {
9100 // Report disconnected services.
9101 if (false) {
9102 // XXX we are letting the client link to the service for
9103 // death notifications.
9104 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009105 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009106 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009107 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009108 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009109 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009110 = r.connections.values().iterator();
9111 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009112 ArrayList<ConnectionRecord> cl = jt.next();
9113 for (int i=0; i<cl.size(); i++) {
9114 ConnectionRecord c = cl.get(i);
9115 if (c.binding.client != app) {
9116 try {
9117 //c.conn.connected(r.className, null);
9118 } catch (Exception e) {
9119 // todo: this should be asynchronous!
9120 Slog.w(TAG, "Exception thrown disconnected servce "
9121 + r.shortName
9122 + " from app " + app.processName, e);
9123 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009124 }
9125 }
9126 }
9127 }
9128 }
9129 }
9130 }
9131
9132 // Clean up any connections this application has to other services.
9133 if (app.connections.size() > 0) {
9134 Iterator<ConnectionRecord> it = app.connections.iterator();
9135 while (it.hasNext()) {
9136 ConnectionRecord r = it.next();
9137 removeConnectionLocked(r, app, null);
9138 }
9139 }
9140 app.connections.clear();
9141
9142 if (app.services.size() != 0) {
9143 // Any services running in the application need to be placed
9144 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009145 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009146 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009147 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009148 synchronized (sr.stats.getBatteryStats()) {
9149 sr.stats.stopLaunchedLocked();
9150 }
9151 sr.app = null;
9152 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009153 if (mStoppingServices.remove(sr)) {
9154 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9155 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009156
9157 boolean hasClients = sr.bindings.size() > 0;
9158 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009159 Iterator<IntentBindRecord> bindings
9160 = sr.bindings.values().iterator();
9161 while (bindings.hasNext()) {
9162 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009163 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009164 + ": shouldUnbind=" + b.hasBound);
9165 b.binder = null;
9166 b.requested = b.received = b.hasBound = false;
9167 }
9168 }
9169
Dianne Hackborn070783f2010-12-29 16:46:28 -08009170 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9171 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009172 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009173 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009174 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009175 sr.crashCount, sr.shortName, app.pid);
9176 bringDownServiceLocked(sr, true);
9177 } else if (!allowRestart) {
9178 bringDownServiceLocked(sr, true);
9179 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009180 boolean canceled = scheduleServiceRestartLocked(sr, true);
9181
9182 // Should the service remain running? Note that in the
9183 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009184 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009185 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9186 if (sr.pendingStarts.size() == 0) {
9187 sr.startRequested = false;
9188 if (!hasClients) {
9189 // Whoops, no reason to restart!
9190 bringDownServiceLocked(sr, true);
9191 }
9192 }
9193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009194 }
9195 }
9196
9197 if (!allowRestart) {
9198 app.services.clear();
9199 }
9200 }
9201
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009202 // Make sure we have no more records on the stopping list.
9203 int i = mStoppingServices.size();
9204 while (i > 0) {
9205 i--;
9206 ServiceRecord sr = mStoppingServices.get(i);
9207 if (sr.app == app) {
9208 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009209 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009210 }
9211 }
9212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009213 app.executingServices.clear();
9214 }
9215
9216 private final void removeDyingProviderLocked(ProcessRecord proc,
9217 ContentProviderRecord cpr) {
9218 synchronized (cpr) {
9219 cpr.launchingApp = null;
9220 cpr.notifyAll();
9221 }
9222
9223 mProvidersByClass.remove(cpr.info.name);
9224 String names[] = cpr.info.authority.split(";");
9225 for (int j = 0; j < names.length; j++) {
9226 mProvidersByName.remove(names[j]);
9227 }
9228
9229 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9230 while (cit.hasNext()) {
9231 ProcessRecord capp = cit.next();
9232 if (!capp.persistent && capp.thread != null
9233 && capp.pid != 0
9234 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009235 Slog.i(TAG, "Kill " + capp.processName
9236 + " (pid " + capp.pid + "): provider " + cpr.info.name
9237 + " in dying process " + proc.processName);
9238 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9239 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009240 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009241 }
9242 }
9243
9244 mLaunchingProviders.remove(cpr);
9245 }
9246
9247 /**
9248 * Main code for cleaning up a process when it has gone away. This is
9249 * called both as a result of the process dying, or directly when stopping
9250 * a process when running in single process mode.
9251 */
9252 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009253 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009255 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009256 }
9257
Dianne Hackborn36124872009-10-08 16:22:03 -07009258 mProcessesToGc.remove(app);
9259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009260 // Dismiss any open dialogs.
9261 if (app.crashDialog != null) {
9262 app.crashDialog.dismiss();
9263 app.crashDialog = null;
9264 }
9265 if (app.anrDialog != null) {
9266 app.anrDialog.dismiss();
9267 app.anrDialog = null;
9268 }
9269 if (app.waitDialog != null) {
9270 app.waitDialog.dismiss();
9271 app.waitDialog = null;
9272 }
9273
9274 app.crashing = false;
9275 app.notResponding = false;
9276
9277 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009278 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009279 app.thread = null;
9280 app.forcingToForeground = null;
9281 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009282 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009283 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009284 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009285
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009286 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009287
9288 boolean restart = false;
9289
9290 int NL = mLaunchingProviders.size();
9291
9292 // Remove published content providers.
9293 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009294 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009295 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009296 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009297 cpr.provider = null;
9298 cpr.app = null;
9299
9300 // See if someone is waiting for this provider... in which
9301 // case we don't remove it, but just let it restart.
9302 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009303 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009304 for (; i<NL; i++) {
9305 if (mLaunchingProviders.get(i) == cpr) {
9306 restart = true;
9307 break;
9308 }
9309 }
9310 } else {
9311 i = NL;
9312 }
9313
9314 if (i >= NL) {
9315 removeDyingProviderLocked(app, cpr);
9316 NL = mLaunchingProviders.size();
9317 }
9318 }
9319 app.pubProviders.clear();
9320 }
9321
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009322 // Take care of any launching providers waiting for this process.
9323 if (checkAppInLaunchingProvidersLocked(app, false)) {
9324 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009325 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009327 // Unregister from connected content providers.
9328 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009329 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009330 while (it.hasNext()) {
9331 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9332 cpr.clients.remove(app);
9333 }
9334 app.conProviders.clear();
9335 }
9336
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009337 // At this point there may be remaining entries in mLaunchingProviders
9338 // where we were the only one waiting, so they are no longer of use.
9339 // Look for these and clean up if found.
9340 // XXX Commented out for now. Trying to figure out a way to reproduce
9341 // the actual situation to identify what is actually going on.
9342 if (false) {
9343 for (int i=0; i<NL; i++) {
9344 ContentProviderRecord cpr = (ContentProviderRecord)
9345 mLaunchingProviders.get(i);
9346 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9347 synchronized (cpr) {
9348 cpr.launchingApp = null;
9349 cpr.notifyAll();
9350 }
9351 }
9352 }
9353 }
9354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009355 skipCurrentReceiverLocked(app);
9356
9357 // Unregister any receivers.
9358 if (app.receivers.size() > 0) {
9359 Iterator<ReceiverList> it = app.receivers.iterator();
9360 while (it.hasNext()) {
9361 removeReceiverLocked(it.next());
9362 }
9363 app.receivers.clear();
9364 }
9365
Christopher Tate181fafa2009-05-14 11:12:14 -07009366 // If the app is undergoing backup, tell the backup manager about it
9367 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009368 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009369 try {
9370 IBackupManager bm = IBackupManager.Stub.asInterface(
9371 ServiceManager.getService(Context.BACKUP_SERVICE));
9372 bm.agentDisconnected(app.info.packageName);
9373 } catch (RemoteException e) {
9374 // can't happen; backup manager is local
9375 }
9376 }
9377
Jeff Sharkey287bd832011-05-28 19:36:26 -07009378 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009379
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009380 // If the caller is restarting this app, then leave it in its
9381 // current lists and let the caller take care of it.
9382 if (restarting) {
9383 return;
9384 }
9385
9386 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009387 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009388 "Removing non-persistent process during cleanup: " + app);
9389 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009390 if (mHeavyWeightProcess == app) {
9391 mHeavyWeightProcess = null;
9392 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9393 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009394 } else if (!app.removed) {
9395 // This app is persistent, so we need to keep its record around.
9396 // If it is not already on the pending app list, add it there
9397 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009398 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9399 mPersistentStartingProcesses.add(app);
9400 restart = true;
9401 }
9402 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009403 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9404 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009405 mProcessesOnHold.remove(app);
9406
The Android Open Source Project4df24232009-03-05 14:34:35 -08009407 if (app == mHomeProcess) {
9408 mHomeProcess = null;
9409 }
9410
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009411 if (restart) {
9412 // We have components that still need to be running in the
9413 // process, so re-launch it.
9414 mProcessNames.put(app.processName, app.info.uid, app);
9415 startProcessLocked(app, "restart", app.processName);
9416 } else if (app.pid > 0 && app.pid != MY_PID) {
9417 // Goodbye!
9418 synchronized (mPidsSelfLocked) {
9419 mPidsSelfLocked.remove(app.pid);
9420 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9421 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009422 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009423 }
9424 }
9425
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009426 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9427 // Look through the content providers we are waiting to have launched,
9428 // and if any run in this process then either schedule a restart of
9429 // the process or kill the client waiting for it if this process has
9430 // gone bad.
9431 int NL = mLaunchingProviders.size();
9432 boolean restart = false;
9433 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009434 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009435 if (cpr.launchingApp == app) {
9436 if (!alwaysBad && !app.bad) {
9437 restart = true;
9438 } else {
9439 removeDyingProviderLocked(app, cpr);
9440 NL = mLaunchingProviders.size();
9441 }
9442 }
9443 }
9444 return restart;
9445 }
9446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009447 // =========================================================
9448 // SERVICES
9449 // =========================================================
9450
9451 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9452 ActivityManager.RunningServiceInfo info =
9453 new ActivityManager.RunningServiceInfo();
9454 info.service = r.name;
9455 if (r.app != null) {
9456 info.pid = r.app.pid;
9457 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009458 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009459 info.process = r.processName;
9460 info.foreground = r.isForeground;
9461 info.activeSince = r.createTime;
9462 info.started = r.startRequested;
9463 info.clientCount = r.connections.size();
9464 info.crashCount = r.crashCount;
9465 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009466 if (r.isForeground) {
9467 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9468 }
9469 if (r.startRequested) {
9470 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9471 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009472 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009473 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9474 }
9475 if (r.app != null && r.app.persistent) {
9476 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9477 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009478
9479 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9480 for (int i=0; i<connl.size(); i++) {
9481 ConnectionRecord conn = connl.get(i);
9482 if (conn.clientLabel != 0) {
9483 info.clientPackage = conn.binding.client.info.packageName;
9484 info.clientLabel = conn.clientLabel;
9485 return info;
9486 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009487 }
9488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009489 return info;
9490 }
9491
9492 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9493 int flags) {
9494 synchronized (this) {
9495 ArrayList<ActivityManager.RunningServiceInfo> res
9496 = new ArrayList<ActivityManager.RunningServiceInfo>();
9497
9498 if (mServices.size() > 0) {
9499 Iterator<ServiceRecord> it = mServices.values().iterator();
9500 while (it.hasNext() && res.size() < maxNum) {
9501 res.add(makeRunningServiceInfoLocked(it.next()));
9502 }
9503 }
9504
9505 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9506 ServiceRecord r = mRestartingServices.get(i);
9507 ActivityManager.RunningServiceInfo info =
9508 makeRunningServiceInfoLocked(r);
9509 info.restarting = r.nextRestartTime;
9510 res.add(info);
9511 }
9512
9513 return res;
9514 }
9515 }
9516
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009517 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9518 synchronized (this) {
9519 ServiceRecord r = mServices.get(name);
9520 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009521 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9522 for (int i=0; i<conn.size(); i++) {
9523 if (conn.get(i).clientIntent != null) {
9524 return conn.get(i).clientIntent;
9525 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009526 }
9527 }
9528 }
9529 }
9530 return null;
9531 }
9532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009533 private final ServiceRecord findServiceLocked(ComponentName name,
9534 IBinder token) {
9535 ServiceRecord r = mServices.get(name);
9536 return r == token ? r : null;
9537 }
9538
9539 private final class ServiceLookupResult {
9540 final ServiceRecord record;
9541 final String permission;
9542
9543 ServiceLookupResult(ServiceRecord _record, String _permission) {
9544 record = _record;
9545 permission = _permission;
9546 }
9547 };
9548
9549 private ServiceLookupResult findServiceLocked(Intent service,
9550 String resolvedType) {
9551 ServiceRecord r = null;
9552 if (service.getComponent() != null) {
9553 r = mServices.get(service.getComponent());
9554 }
9555 if (r == null) {
9556 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9557 r = mServicesByIntent.get(filter);
9558 }
9559
9560 if (r == null) {
9561 try {
9562 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009563 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009564 service, resolvedType, 0);
9565 ServiceInfo sInfo =
9566 rInfo != null ? rInfo.serviceInfo : null;
9567 if (sInfo == null) {
9568 return null;
9569 }
9570
9571 ComponentName name = new ComponentName(
9572 sInfo.applicationInfo.packageName, sInfo.name);
9573 r = mServices.get(name);
9574 } catch (RemoteException ex) {
9575 // pm is in same process, this will never happen.
9576 }
9577 }
9578 if (r != null) {
9579 int callingPid = Binder.getCallingPid();
9580 int callingUid = Binder.getCallingUid();
9581 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009582 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009583 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009584 if (!r.exported) {
9585 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9586 + " from pid=" + callingPid
9587 + ", uid=" + callingUid
9588 + " that is not exported from uid " + r.appInfo.uid);
9589 return new ServiceLookupResult(null, "not exported from uid "
9590 + r.appInfo.uid);
9591 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009592 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009593 + " from pid=" + callingPid
9594 + ", uid=" + callingUid
9595 + " requires " + r.permission);
9596 return new ServiceLookupResult(null, r.permission);
9597 }
9598 return new ServiceLookupResult(r, null);
9599 }
9600 return null;
9601 }
9602
9603 private class ServiceRestarter implements Runnable {
9604 private ServiceRecord mService;
9605
9606 void setService(ServiceRecord service) {
9607 mService = service;
9608 }
9609
9610 public void run() {
9611 synchronized(ActivityManagerService.this) {
9612 performServiceRestartLocked(mService);
9613 }
9614 }
9615 }
9616
9617 private ServiceLookupResult retrieveServiceLocked(Intent service,
9618 String resolvedType, int callingPid, int callingUid) {
9619 ServiceRecord r = null;
9620 if (service.getComponent() != null) {
9621 r = mServices.get(service.getComponent());
9622 }
9623 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9624 r = mServicesByIntent.get(filter);
9625 if (r == null) {
9626 try {
9627 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009628 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009629 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009630 ServiceInfo sInfo =
9631 rInfo != null ? rInfo.serviceInfo : null;
9632 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009633 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009634 ": not found");
9635 return null;
9636 }
9637
9638 ComponentName name = new ComponentName(
9639 sInfo.applicationInfo.packageName, sInfo.name);
9640 r = mServices.get(name);
9641 if (r == null) {
9642 filter = new Intent.FilterComparison(service.cloneFilter());
9643 ServiceRestarter res = new ServiceRestarter();
9644 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9645 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9646 synchronized (stats) {
9647 ss = stats.getServiceStatsLocked(
9648 sInfo.applicationInfo.uid, sInfo.packageName,
9649 sInfo.name);
9650 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009651 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009652 res.setService(r);
9653 mServices.put(name, r);
9654 mServicesByIntent.put(filter, r);
9655
9656 // Make sure this component isn't in the pending list.
9657 int N = mPendingServices.size();
9658 for (int i=0; i<N; i++) {
9659 ServiceRecord pr = mPendingServices.get(i);
9660 if (pr.name.equals(name)) {
9661 mPendingServices.remove(i);
9662 i--;
9663 N--;
9664 }
9665 }
9666 }
9667 } catch (RemoteException ex) {
9668 // pm is in same process, this will never happen.
9669 }
9670 }
9671 if (r != null) {
9672 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009673 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009675 if (!r.exported) {
9676 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9677 + " from pid=" + callingPid
9678 + ", uid=" + callingUid
9679 + " that is not exported from uid " + r.appInfo.uid);
9680 return new ServiceLookupResult(null, "not exported from uid "
9681 + r.appInfo.uid);
9682 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009683 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009684 + " from pid=" + callingPid
9685 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009686 + " requires " + r.permission);
9687 return new ServiceLookupResult(null, r.permission);
9688 }
9689 return new ServiceLookupResult(r, null);
9690 }
9691 return null;
9692 }
9693
Dianne Hackborn287952c2010-09-22 22:34:31 -07009694 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9695 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9696 + why + " of " + r + " in app " + r.app);
9697 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9698 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009699 long now = SystemClock.uptimeMillis();
9700 if (r.executeNesting == 0 && r.app != null) {
9701 if (r.app.executingServices.size() == 0) {
9702 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9703 msg.obj = r.app;
9704 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9705 }
9706 r.app.executingServices.add(r);
9707 }
9708 r.executeNesting++;
9709 r.executingStart = now;
9710 }
9711
9712 private final void sendServiceArgsLocked(ServiceRecord r,
9713 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009714 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009715 if (N == 0) {
9716 return;
9717 }
9718
Dianne Hackborn39792d22010-08-19 18:01:52 -07009719 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009720 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009721 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009722 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9723 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009724 if (si.intent == null && N > 1) {
9725 // If somehow we got a dummy null intent in the middle,
9726 // then skip it. DO NOT skip a null intent when it is
9727 // the only one in the list -- this is to support the
9728 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009729 continue;
9730 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009731 si.deliveredTime = SystemClock.uptimeMillis();
9732 r.deliveredStarts.add(si);
9733 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009734 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009735 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009736 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009737 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009738 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009739 if (!oomAdjusted) {
9740 oomAdjusted = true;
9741 updateOomAdjLocked(r.app);
9742 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009743 int flags = 0;
9744 if (si.deliveryCount > 0) {
9745 flags |= Service.START_FLAG_RETRY;
9746 }
9747 if (si.doneExecutingCount > 0) {
9748 flags |= Service.START_FLAG_REDELIVERY;
9749 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009750 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009751 } catch (RemoteException e) {
9752 // Remote process gone... we'll let the normal cleanup take
9753 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009754 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009755 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009756 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009757 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009758 break;
9759 }
9760 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009761 }
9762
9763 private final boolean requestServiceBindingLocked(ServiceRecord r,
9764 IntentBindRecord i, boolean rebind) {
9765 if (r.app == null || r.app.thread == null) {
9766 // If service is not currently running, can't yet bind.
9767 return false;
9768 }
9769 if ((!i.requested || rebind) && i.apps.size() > 0) {
9770 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009771 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009772 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9773 if (!rebind) {
9774 i.requested = true;
9775 }
9776 i.hasBound = true;
9777 i.doRebind = false;
9778 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009779 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009780 return false;
9781 }
9782 }
9783 return true;
9784 }
9785
9786 private final void requestServiceBindingsLocked(ServiceRecord r) {
9787 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9788 while (bindings.hasNext()) {
9789 IntentBindRecord i = bindings.next();
9790 if (!requestServiceBindingLocked(r, i, false)) {
9791 break;
9792 }
9793 }
9794 }
9795
9796 private final void realStartServiceLocked(ServiceRecord r,
9797 ProcessRecord app) throws RemoteException {
9798 if (app.thread == null) {
9799 throw new RemoteException();
9800 }
9801
9802 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009803 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009804
9805 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009806 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009807 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009808
9809 boolean created = false;
9810 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009811 mStringBuilder.setLength(0);
9812 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009813 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009814 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009815 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816 synchronized (r.stats.getBatteryStats()) {
9817 r.stats.startLaunchedLocked();
9818 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009819 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009820 app.thread.scheduleCreateService(r, r.serviceInfo,
9821 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009822 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009823 created = true;
9824 } finally {
9825 if (!created) {
9826 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009827 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009828 }
9829 }
9830
9831 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009832
9833 // If the service is in the started state, and there are no
9834 // pending arguments, then fake up one so its onStartCommand() will
9835 // be called.
9836 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009837 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
9838 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009839 }
9840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009841 sendServiceArgsLocked(r, true);
9842 }
9843
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009844 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
9845 boolean allowCancel) {
9846 boolean canceled = false;
9847
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009848 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009849 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -07009850 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009851
Dianne Hackborn070783f2010-12-29 16:46:28 -08009852 if ((r.serviceInfo.applicationInfo.flags
9853 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9854 minDuration /= 4;
9855 }
9856
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009857 // Any delivered but not yet finished starts should be put back
9858 // on the pending list.
9859 final int N = r.deliveredStarts.size();
9860 if (N > 0) {
9861 for (int i=N-1; i>=0; i--) {
9862 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -07009863 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009864 if (si.intent == null) {
9865 // We'll generate this again if needed.
9866 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
9867 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
9868 r.pendingStarts.add(0, si);
9869 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
9870 dur *= 2;
9871 if (minDuration < dur) minDuration = dur;
9872 if (resetTime < dur) resetTime = dur;
9873 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009874 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009875 + r.name);
9876 canceled = true;
9877 }
9878 }
9879 r.deliveredStarts.clear();
9880 }
9881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009882 r.totalRestartCount++;
9883 if (r.restartDelay == 0) {
9884 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009885 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009886 } else {
9887 // If it has been a "reasonably long time" since the service
9888 // was started, then reset our restart duration back to
9889 // the beginning, so we don't infinitely increase the duration
9890 // on a service that just occasionally gets killed (which is
9891 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009892 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009893 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009894 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009895 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -08009896 if ((r.serviceInfo.applicationInfo.flags
9897 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
9898 // Services in peristent processes will restart much more
9899 // quickly, since they are pretty important. (Think SystemUI).
9900 r.restartDelay += minDuration/2;
9901 } else {
9902 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
9903 if (r.restartDelay < minDuration) {
9904 r.restartDelay = minDuration;
9905 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009907 }
9908 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009909
9910 r.nextRestartTime = now + r.restartDelay;
9911
9912 // Make sure that we don't end up restarting a bunch of services
9913 // all at the same time.
9914 boolean repeat;
9915 do {
9916 repeat = false;
9917 for (int i=mRestartingServices.size()-1; i>=0; i--) {
9918 ServiceRecord r2 = mRestartingServices.get(i);
9919 if (r2 != r && r.nextRestartTime
9920 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
9921 && r.nextRestartTime
9922 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
9923 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
9924 r.restartDelay = r.nextRestartTime - now;
9925 repeat = true;
9926 break;
9927 }
9928 }
9929 } while (repeat);
9930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009931 if (!mRestartingServices.contains(r)) {
9932 mRestartingServices.add(r);
9933 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009934
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009935 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009937 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009938 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009939 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -08009940 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009941 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -08009942 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009943 r.shortName, r.restartDelay);
9944
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009945 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009946 }
9947
9948 final void performServiceRestartLocked(ServiceRecord r) {
9949 if (!mRestartingServices.contains(r)) {
9950 return;
9951 }
9952 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
9953 }
9954
9955 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
9956 if (r.restartDelay == 0) {
9957 return false;
9958 }
9959 r.resetRestartCounter();
9960 mRestartingServices.remove(r);
9961 mHandler.removeCallbacks(r.restarter);
9962 return true;
9963 }
9964
9965 private final boolean bringUpServiceLocked(ServiceRecord r,
9966 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009967 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009968 //r.dump(" ");
9969
Dianne Hackborn36124872009-10-08 16:22:03 -07009970 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009971 sendServiceArgsLocked(r, false);
9972 return true;
9973 }
9974
9975 if (!whileRestarting && r.restartDelay > 0) {
9976 // If waiting for a restart, then do nothing.
9977 return true;
9978 }
9979
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009980 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009982 // We are now bringing the service up, so no longer in the
9983 // restarting state.
9984 mRestartingServices.remove(r);
9985
Dianne Hackborne7f97212011-02-24 14:40:20 -08009986 // Service is now being launched, its package can't be stopped.
9987 try {
9988 AppGlobals.getPackageManager().setPackageStoppedState(
9989 r.packageName, false);
9990 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08009991 } catch (IllegalArgumentException e) {
9992 Slog.w(TAG, "Failed trying to unstop package "
9993 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08009994 }
9995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009996 final String appName = r.processName;
9997 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
9998 if (app != null && app.thread != null) {
9999 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010000 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010001 realStartServiceLocked(r, app);
10002 return true;
10003 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010004 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010005 }
10006
10007 // If a dead object exception was thrown -- fall through to
10008 // restart the application.
10009 }
10010
Dianne Hackborn36124872009-10-08 16:22:03 -070010011 // Not running -- get it started, and enqueue this service record
10012 // to be executed when the app comes up.
10013 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10014 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010015 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010016 + r.appInfo.packageName + "/"
10017 + r.appInfo.uid + " for service "
10018 + r.intent.getIntent() + ": process is bad");
10019 bringDownServiceLocked(r, true);
10020 return false;
10021 }
10022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010023 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010024 mPendingServices.add(r);
10025 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010027 return true;
10028 }
10029
10030 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010031 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010032 //r.dump(" ");
10033
10034 // Does it still need to run?
10035 if (!force && r.startRequested) {
10036 return;
10037 }
10038 if (r.connections.size() > 0) {
10039 if (!force) {
10040 // XXX should probably keep a count of the number of auto-create
10041 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010042 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010043 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010044 ArrayList<ConnectionRecord> cr = it.next();
10045 for (int i=0; i<cr.size(); i++) {
10046 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10047 return;
10048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010049 }
10050 }
10051 }
10052
10053 // Report to all of the connections that the service is no longer
10054 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010055 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010056 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010057 ArrayList<ConnectionRecord> c = it.next();
10058 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010059 ConnectionRecord cr = c.get(i);
10060 // There is still a connection to the service that is
10061 // being brought down. Mark it as dead.
10062 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010063 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010064 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010065 } catch (Exception e) {
10066 Slog.w(TAG, "Failure disconnecting service " + r.name +
10067 " to connection " + c.get(i).conn.asBinder() +
10068 " (in " + c.get(i).binding.client.processName + ")", e);
10069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010070 }
10071 }
10072 }
10073
10074 // Tell the service that it has been unbound.
10075 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10076 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10077 while (it.hasNext()) {
10078 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010079 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010080 + ": hasBound=" + ibr.hasBound);
10081 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10082 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010083 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010084 updateOomAdjLocked(r.app);
10085 ibr.hasBound = false;
10086 r.app.thread.scheduleUnbindService(r,
10087 ibr.intent.getIntent());
10088 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010089 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010090 + r.shortName, e);
10091 serviceDoneExecutingLocked(r, true);
10092 }
10093 }
10094 }
10095 }
10096
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010097 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010098 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010099 System.identityHashCode(r), r.shortName,
10100 (r.app != null) ? r.app.pid : -1);
10101
10102 mServices.remove(r.name);
10103 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010104 r.totalRestartCount = 0;
10105 unscheduleServiceRestartLocked(r);
10106
10107 // Also make sure it is not on the pending list.
10108 int N = mPendingServices.size();
10109 for (int i=0; i<N; i++) {
10110 if (mPendingServices.get(i) == r) {
10111 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010112 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010113 i--;
10114 N--;
10115 }
10116 }
10117
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010118 r.cancelNotification();
10119 r.isForeground = false;
10120 r.foregroundId = 0;
10121 r.foregroundNoti = null;
10122
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010123 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010124 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010125 r.pendingStarts.clear();
10126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010127 if (r.app != null) {
10128 synchronized (r.stats.getBatteryStats()) {
10129 r.stats.stopLaunchedLocked();
10130 }
10131 r.app.services.remove(r);
10132 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010133 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010134 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010135 mStoppingServices.add(r);
10136 updateOomAdjLocked(r.app);
10137 r.app.thread.scheduleStopService(r);
10138 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010139 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010140 + r.shortName, e);
10141 serviceDoneExecutingLocked(r, true);
10142 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010143 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010144 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010145 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010146 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010147 }
10148 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010149 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010150 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010151 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010152
10153 if (r.bindings.size() > 0) {
10154 r.bindings.clear();
10155 }
10156
10157 if (r.restarter instanceof ServiceRestarter) {
10158 ((ServiceRestarter)r.restarter).setService(null);
10159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010160 }
10161
10162 ComponentName startServiceLocked(IApplicationThread caller,
10163 Intent service, String resolvedType,
10164 int callingPid, int callingUid) {
10165 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010166 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010167 + " type=" + resolvedType + " args=" + service.getExtras());
10168
10169 if (caller != null) {
10170 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10171 if (callerApp == null) {
10172 throw new SecurityException(
10173 "Unable to find app for caller " + caller
10174 + " (pid=" + Binder.getCallingPid()
10175 + ") when starting service " + service);
10176 }
10177 }
10178
10179 ServiceLookupResult res =
10180 retrieveServiceLocked(service, resolvedType,
10181 callingPid, callingUid);
10182 if (res == null) {
10183 return null;
10184 }
10185 if (res.record == null) {
10186 return new ComponentName("!", res.permission != null
10187 ? res.permission : "private to package");
10188 }
10189 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010190 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10191 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010192 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010193 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010194 }
10195 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010196 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010197 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010198 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199 r.lastActivity = SystemClock.uptimeMillis();
10200 synchronized (r.stats.getBatteryStats()) {
10201 r.stats.startRunningLocked();
10202 }
10203 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10204 return new ComponentName("!", "Service process is bad");
10205 }
10206 return r.name;
10207 }
10208 }
10209
10210 public ComponentName startService(IApplicationThread caller, Intent service,
10211 String resolvedType) {
10212 // Refuse possible leaked file descriptors
10213 if (service != null && service.hasFileDescriptors() == true) {
10214 throw new IllegalArgumentException("File descriptors passed in Intent");
10215 }
10216
10217 synchronized(this) {
10218 final int callingPid = Binder.getCallingPid();
10219 final int callingUid = Binder.getCallingUid();
10220 final long origId = Binder.clearCallingIdentity();
10221 ComponentName res = startServiceLocked(caller, service,
10222 resolvedType, callingPid, callingUid);
10223 Binder.restoreCallingIdentity(origId);
10224 return res;
10225 }
10226 }
10227
10228 ComponentName startServiceInPackage(int uid,
10229 Intent service, String resolvedType) {
10230 synchronized(this) {
10231 final long origId = Binder.clearCallingIdentity();
10232 ComponentName res = startServiceLocked(null, service,
10233 resolvedType, -1, uid);
10234 Binder.restoreCallingIdentity(origId);
10235 return res;
10236 }
10237 }
10238
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010239 private void stopServiceLocked(ServiceRecord service) {
10240 synchronized (service.stats.getBatteryStats()) {
10241 service.stats.stopRunningLocked();
10242 }
10243 service.startRequested = false;
10244 service.callStart = false;
10245 bringDownServiceLocked(service, false);
10246 }
10247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010248 public int stopService(IApplicationThread caller, Intent service,
10249 String resolvedType) {
10250 // Refuse possible leaked file descriptors
10251 if (service != null && service.hasFileDescriptors() == true) {
10252 throw new IllegalArgumentException("File descriptors passed in Intent");
10253 }
10254
10255 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010256 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010257 + " type=" + resolvedType);
10258
10259 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10260 if (caller != null && callerApp == null) {
10261 throw new SecurityException(
10262 "Unable to find app for caller " + caller
10263 + " (pid=" + Binder.getCallingPid()
10264 + ") when stopping service " + service);
10265 }
10266
10267 // If this service is active, make sure it is stopped.
10268 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10269 if (r != null) {
10270 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010271 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010272 try {
10273 stopServiceLocked(r.record);
10274 } finally {
10275 Binder.restoreCallingIdentity(origId);
10276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010277 return 1;
10278 }
10279 return -1;
10280 }
10281 }
10282
10283 return 0;
10284 }
10285
10286 public IBinder peekService(Intent service, String resolvedType) {
10287 // Refuse possible leaked file descriptors
10288 if (service != null && service.hasFileDescriptors() == true) {
10289 throw new IllegalArgumentException("File descriptors passed in Intent");
10290 }
10291
10292 IBinder ret = null;
10293
10294 synchronized(this) {
10295 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10296
10297 if (r != null) {
10298 // r.record is null if findServiceLocked() failed the caller permission check
10299 if (r.record == null) {
10300 throw new SecurityException(
10301 "Permission Denial: Accessing service " + r.record.name
10302 + " from pid=" + Binder.getCallingPid()
10303 + ", uid=" + Binder.getCallingUid()
10304 + " requires " + r.permission);
10305 }
10306 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10307 if (ib != null) {
10308 ret = ib.binder;
10309 }
10310 }
10311 }
10312
10313 return ret;
10314 }
10315
10316 public boolean stopServiceToken(ComponentName className, IBinder token,
10317 int startId) {
10318 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010319 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010320 + " " + token + " startId=" + startId);
10321 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010322 if (r != null) {
10323 if (startId >= 0) {
10324 // Asked to only stop if done with all work. Note that
10325 // to avoid leaks, we will take this as dropping all
10326 // start items up to and including this one.
10327 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10328 if (si != null) {
10329 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010330 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10331 cur.removeUriPermissionsLocked();
10332 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010333 break;
10334 }
10335 }
10336 }
10337
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010338 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010339 return false;
10340 }
10341
10342 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010343 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010344 + " is last, but have " + r.deliveredStarts.size()
10345 + " remaining args");
10346 }
10347 }
10348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010349 synchronized (r.stats.getBatteryStats()) {
10350 r.stats.stopRunningLocked();
10351 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010352 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010353 }
10354 final long origId = Binder.clearCallingIdentity();
10355 bringDownServiceLocked(r, false);
10356 Binder.restoreCallingIdentity(origId);
10357 return true;
10358 }
10359 }
10360 return false;
10361 }
10362
10363 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010364 int id, Notification notification, boolean removeNotification) {
10365 final long origId = Binder.clearCallingIdentity();
10366 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010367 synchronized(this) {
10368 ServiceRecord r = findServiceLocked(className, token);
10369 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010370 if (id != 0) {
10371 if (notification == null) {
10372 throw new IllegalArgumentException("null notification");
10373 }
10374 if (r.foregroundId != id) {
10375 r.cancelNotification();
10376 r.foregroundId = id;
10377 }
10378 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10379 r.foregroundNoti = notification;
10380 r.isForeground = true;
10381 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010382 if (r.app != null) {
10383 updateServiceForegroundLocked(r.app, true);
10384 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010385 } else {
10386 if (r.isForeground) {
10387 r.isForeground = false;
10388 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010389 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010390 updateServiceForegroundLocked(r.app, true);
10391 }
10392 }
10393 if (removeNotification) {
10394 r.cancelNotification();
10395 r.foregroundId = 0;
10396 r.foregroundNoti = null;
10397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010398 }
10399 }
10400 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010401 } finally {
10402 Binder.restoreCallingIdentity(origId);
10403 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010404 }
10405
10406 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10407 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010408 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010409 if (sr.isForeground) {
10410 anyForeground = true;
10411 break;
10412 }
10413 }
10414 if (anyForeground != proc.foregroundServices) {
10415 proc.foregroundServices = anyForeground;
10416 if (oomAdj) {
10417 updateOomAdjLocked();
10418 }
10419 }
10420 }
10421
10422 public int bindService(IApplicationThread caller, IBinder token,
10423 Intent service, String resolvedType,
10424 IServiceConnection connection, int flags) {
10425 // Refuse possible leaked file descriptors
10426 if (service != null && service.hasFileDescriptors() == true) {
10427 throw new IllegalArgumentException("File descriptors passed in Intent");
10428 }
10429
10430 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010431 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010432 + " type=" + resolvedType + " conn=" + connection.asBinder()
10433 + " flags=0x" + Integer.toHexString(flags));
10434 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10435 if (callerApp == null) {
10436 throw new SecurityException(
10437 "Unable to find app for caller " + caller
10438 + " (pid=" + Binder.getCallingPid()
10439 + ") when binding service " + service);
10440 }
10441
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010442 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010444 activity = mMainStack.isInStackLocked(token);
10445 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010446 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010447 return 0;
10448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010449 }
10450
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010451 int clientLabel = 0;
10452 PendingIntent clientIntent = null;
10453
10454 if (callerApp.info.uid == Process.SYSTEM_UID) {
10455 // Hacky kind of thing -- allow system stuff to tell us
10456 // what they are, so we can report this elsewhere for
10457 // others to know why certain services are running.
10458 try {
10459 clientIntent = (PendingIntent)service.getParcelableExtra(
10460 Intent.EXTRA_CLIENT_INTENT);
10461 } catch (RuntimeException e) {
10462 }
10463 if (clientIntent != null) {
10464 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10465 if (clientLabel != 0) {
10466 // There are no useful extras in the intent, trash them.
10467 // System code calling with this stuff just needs to know
10468 // this will happen.
10469 service = service.cloneFilter();
10470 }
10471 }
10472 }
10473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010474 ServiceLookupResult res =
10475 retrieveServiceLocked(service, resolvedType,
10476 Binder.getCallingPid(), Binder.getCallingUid());
10477 if (res == null) {
10478 return 0;
10479 }
10480 if (res.record == null) {
10481 return -1;
10482 }
10483 ServiceRecord s = res.record;
10484
10485 final long origId = Binder.clearCallingIdentity();
10486
10487 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010488 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010489 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010490 }
10491
10492 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10493 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010494 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010495
10496 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010497 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10498 if (clist == null) {
10499 clist = new ArrayList<ConnectionRecord>();
10500 s.connections.put(binder, clist);
10501 }
10502 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010503 b.connections.add(c);
10504 if (activity != null) {
10505 if (activity.connections == null) {
10506 activity.connections = new HashSet<ConnectionRecord>();
10507 }
10508 activity.connections.add(c);
10509 }
10510 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010511 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10512 b.client.hasAboveClient = true;
10513 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010514 clist = mServiceConnections.get(binder);
10515 if (clist == null) {
10516 clist = new ArrayList<ConnectionRecord>();
10517 mServiceConnections.put(binder, clist);
10518 }
10519 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010520
10521 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10522 s.lastActivity = SystemClock.uptimeMillis();
10523 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10524 return 0;
10525 }
10526 }
10527
10528 if (s.app != null) {
10529 // This could have made the service more important.
10530 updateOomAdjLocked(s.app);
10531 }
10532
Joe Onorato8a9b2202010-02-26 18:56:32 -080010533 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010534 + ": received=" + b.intent.received
10535 + " apps=" + b.intent.apps.size()
10536 + " doRebind=" + b.intent.doRebind);
10537
10538 if (s.app != null && b.intent.received) {
10539 // Service is already running, so we can immediately
10540 // publish the connection.
10541 try {
10542 c.conn.connected(s.name, b.intent.binder);
10543 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010544 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010545 + " to connection " + c.conn.asBinder()
10546 + " (in " + c.binding.client.processName + ")", e);
10547 }
10548
10549 // If this is the first app connected back to this binding,
10550 // and the service had previously asked to be told when
10551 // rebound, then do so.
10552 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10553 requestServiceBindingLocked(s, b.intent, true);
10554 }
10555 } else if (!b.intent.requested) {
10556 requestServiceBindingLocked(s, b.intent, false);
10557 }
10558
10559 Binder.restoreCallingIdentity(origId);
10560 }
10561
10562 return 1;
10563 }
10564
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010565 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010566 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010567 IBinder binder = c.conn.asBinder();
10568 AppBindRecord b = c.binding;
10569 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010570 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10571 if (clist != null) {
10572 clist.remove(c);
10573 if (clist.size() == 0) {
10574 s.connections.remove(binder);
10575 }
10576 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010577 b.connections.remove(c);
10578 if (c.activity != null && c.activity != skipAct) {
10579 if (c.activity.connections != null) {
10580 c.activity.connections.remove(c);
10581 }
10582 }
10583 if (b.client != skipApp) {
10584 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010585 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10586 b.client.updateHasAboveClientLocked();
10587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010588 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010589 clist = mServiceConnections.get(binder);
10590 if (clist != null) {
10591 clist.remove(c);
10592 if (clist.size() == 0) {
10593 mServiceConnections.remove(binder);
10594 }
10595 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010596
10597 if (b.connections.size() == 0) {
10598 b.intent.apps.remove(b.client);
10599 }
10600
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010601 if (!c.serviceDead) {
10602 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10603 + ": shouldUnbind=" + b.intent.hasBound);
10604 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10605 && b.intent.hasBound) {
10606 try {
10607 bumpServiceExecutingLocked(s, "unbind");
10608 updateOomAdjLocked(s.app);
10609 b.intent.hasBound = false;
10610 // Assume the client doesn't want to know about a rebind;
10611 // we will deal with that later if it asks for one.
10612 b.intent.doRebind = false;
10613 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10614 } catch (Exception e) {
10615 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10616 serviceDoneExecutingLocked(s, true);
10617 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010618 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010619
10620 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10621 bringDownServiceLocked(s, false);
10622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010623 }
10624 }
10625
10626 public boolean unbindService(IServiceConnection connection) {
10627 synchronized (this) {
10628 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010629 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010630 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10631 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010632 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010633 + connection.asBinder());
10634 return false;
10635 }
10636
10637 final long origId = Binder.clearCallingIdentity();
10638
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010639 while (clist.size() > 0) {
10640 ConnectionRecord r = clist.get(0);
10641 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010642
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010643 if (r.binding.service.app != null) {
10644 // This could have made the service less important.
10645 updateOomAdjLocked(r.binding.service.app);
10646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010647 }
10648
10649 Binder.restoreCallingIdentity(origId);
10650 }
10651
10652 return true;
10653 }
10654
10655 public void publishService(IBinder token, Intent intent, IBinder service) {
10656 // Refuse possible leaked file descriptors
10657 if (intent != null && intent.hasFileDescriptors() == true) {
10658 throw new IllegalArgumentException("File descriptors passed in Intent");
10659 }
10660
10661 synchronized(this) {
10662 if (!(token instanceof ServiceRecord)) {
10663 throw new IllegalArgumentException("Invalid service token");
10664 }
10665 ServiceRecord r = (ServiceRecord)token;
10666
10667 final long origId = Binder.clearCallingIdentity();
10668
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010669 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010670 + " " + intent + ": " + service);
10671 if (r != null) {
10672 Intent.FilterComparison filter
10673 = new Intent.FilterComparison(intent);
10674 IntentBindRecord b = r.bindings.get(filter);
10675 if (b != null && !b.received) {
10676 b.binder = service;
10677 b.requested = true;
10678 b.received = true;
10679 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010680 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010681 = r.connections.values().iterator();
10682 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010683 ArrayList<ConnectionRecord> clist = it.next();
10684 for (int i=0; i<clist.size(); i++) {
10685 ConnectionRecord c = clist.get(i);
10686 if (!filter.equals(c.binding.intent.intent)) {
10687 if (DEBUG_SERVICE) Slog.v(
10688 TAG, "Not publishing to: " + c);
10689 if (DEBUG_SERVICE) Slog.v(
10690 TAG, "Bound intent: " + c.binding.intent.intent);
10691 if (DEBUG_SERVICE) Slog.v(
10692 TAG, "Published intent: " + intent);
10693 continue;
10694 }
10695 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10696 try {
10697 c.conn.connected(r.name, service);
10698 } catch (Exception e) {
10699 Slog.w(TAG, "Failure sending service " + r.name +
10700 " to connection " + c.conn.asBinder() +
10701 " (in " + c.binding.client.processName + ")", e);
10702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010703 }
10704 }
10705 }
10706 }
10707
10708 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10709
10710 Binder.restoreCallingIdentity(origId);
10711 }
10712 }
10713 }
10714
10715 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10716 // Refuse possible leaked file descriptors
10717 if (intent != null && intent.hasFileDescriptors() == true) {
10718 throw new IllegalArgumentException("File descriptors passed in Intent");
10719 }
10720
10721 synchronized(this) {
10722 if (!(token instanceof ServiceRecord)) {
10723 throw new IllegalArgumentException("Invalid service token");
10724 }
10725 ServiceRecord r = (ServiceRecord)token;
10726
10727 final long origId = Binder.clearCallingIdentity();
10728
10729 if (r != null) {
10730 Intent.FilterComparison filter
10731 = new Intent.FilterComparison(intent);
10732 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010733 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010734 + " at " + b + ": apps="
10735 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020010736
10737 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010738 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020010739 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010740 // Applications have already bound since the last
10741 // unbind, so just rebind right here.
10742 requestServiceBindingLocked(r, b, true);
10743 } else {
10744 // Note to tell the service the next time there is
10745 // a new client.
10746 b.doRebind = true;
10747 }
10748 }
10749
Per Edelberg78f9fff2010-08-30 20:01:35 +020010750 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010751
10752 Binder.restoreCallingIdentity(origId);
10753 }
10754 }
10755 }
10756
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010757 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010758 synchronized(this) {
10759 if (!(token instanceof ServiceRecord)) {
10760 throw new IllegalArgumentException("Invalid service token");
10761 }
10762 ServiceRecord r = (ServiceRecord)token;
10763 boolean inStopping = mStoppingServices.contains(token);
10764 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010765 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010766 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 + " with incorrect token: given " + token
10768 + ", expected " + r);
10769 return;
10770 }
10771
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010772 if (type == 1) {
10773 // This is a call from a service start... take care of
10774 // book-keeping.
10775 r.callStart = true;
10776 switch (res) {
10777 case Service.START_STICKY_COMPATIBILITY:
10778 case Service.START_STICKY: {
10779 // We are done with the associated start arguments.
10780 r.findDeliveredStart(startId, true);
10781 // Don't stop if killed.
10782 r.stopIfKilled = false;
10783 break;
10784 }
10785 case Service.START_NOT_STICKY: {
10786 // We are done with the associated start arguments.
10787 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010788 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010789 // There is no more work, and this service
10790 // doesn't want to hang around if killed.
10791 r.stopIfKilled = true;
10792 }
10793 break;
10794 }
10795 case Service.START_REDELIVER_INTENT: {
10796 // We'll keep this item until they explicitly
10797 // call stop for it, but keep track of the fact
10798 // that it was delivered.
10799 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10800 if (si != null) {
10801 si.deliveryCount = 0;
10802 si.doneExecutingCount++;
10803 // Don't stop if killed.
10804 r.stopIfKilled = true;
10805 }
10806 break;
10807 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010808 case Service.START_TASK_REMOVED_COMPLETE: {
10809 // Special processing for onTaskRemoved(). Don't
10810 // impact normal onStartCommand() processing.
10811 r.findDeliveredStart(startId, true);
10812 break;
10813 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010814 default:
10815 throw new IllegalArgumentException(
10816 "Unknown service start result: " + res);
10817 }
10818 if (res == Service.START_STICKY_COMPATIBILITY) {
10819 r.callStart = false;
10820 }
10821 }
10822
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010823 final long origId = Binder.clearCallingIdentity();
10824 serviceDoneExecutingLocked(r, inStopping);
10825 Binder.restoreCallingIdentity(origId);
10826 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010827 Slog.w(TAG, "Done executing unknown service from pid "
10828 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 }
10830 }
10831 }
10832
10833 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010834 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
10835 + ": nesting=" + r.executeNesting
10836 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010837 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010838 r.executeNesting--;
10839 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010840 if (DEBUG_SERVICE) Slog.v(TAG,
10841 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 r.app.executingServices.remove(r);
10843 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010844 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
10845 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010846 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
10847 }
10848 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010849 if (DEBUG_SERVICE) Slog.v(TAG,
10850 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020010852 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010853 }
10854 updateOomAdjLocked(r.app);
10855 }
10856 }
10857
10858 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010859 String anrMessage = null;
10860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010861 synchronized(this) {
10862 if (proc.executingServices.size() == 0 || proc.thread == null) {
10863 return;
10864 }
10865 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
10866 Iterator<ServiceRecord> it = proc.executingServices.iterator();
10867 ServiceRecord timeout = null;
10868 long nextTime = 0;
10869 while (it.hasNext()) {
10870 ServiceRecord sr = it.next();
10871 if (sr.executingStart < maxTime) {
10872 timeout = sr;
10873 break;
10874 }
10875 if (sr.executingStart > nextTime) {
10876 nextTime = sr.executingStart;
10877 }
10878 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010879 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010880 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010881 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010882 } else {
10883 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10884 msg.obj = proc;
10885 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
10886 }
10887 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010888
10889 if (anrMessage != null) {
10890 appNotResponding(proc, null, null, anrMessage);
10891 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010892 }
10893
10894 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010895 // BACKUP AND RESTORE
10896 // =========================================================
10897
10898 // Cause the target app to be launched if necessary and its backup agent
10899 // instantiated. The backup agent will invoke backupAgentCreated() on the
10900 // activity manager to announce its creation.
10901 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010902 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010903 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10904
10905 synchronized(this) {
10906 // !!! TODO: currently no check here that we're already bound
10907 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10908 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10909 synchronized (stats) {
10910 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10911 }
10912
Dianne Hackborne7f97212011-02-24 14:40:20 -080010913 // Backup agent is now in use, its package can't be stopped.
10914 try {
10915 AppGlobals.getPackageManager().setPackageStoppedState(
10916 app.packageName, false);
10917 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010918 } catch (IllegalArgumentException e) {
10919 Slog.w(TAG, "Failed trying to unstop package "
10920 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010921 }
10922
Christopher Tate181fafa2009-05-14 11:12:14 -070010923 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010924 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10925 ? new ComponentName(app.packageName, app.backupAgentName)
10926 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010927 // startProcessLocked() returns existing proc's record if it's already running
10928 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070010929 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010930 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010931 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010932 return false;
10933 }
10934
10935 r.app = proc;
10936 mBackupTarget = r;
10937 mBackupAppName = app.packageName;
10938
Christopher Tate6fa95972009-06-05 18:43:55 -070010939 // Try not to kill the process during backup
10940 updateOomAdjLocked(proc);
10941
Christopher Tate181fafa2009-05-14 11:12:14 -070010942 // If the process is already attached, schedule the creation of the backup agent now.
10943 // If it is not yet live, this will be done when it attaches to the framework.
10944 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010945 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010946 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010947 proc.thread.scheduleCreateBackupAgent(app,
10948 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010949 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010950 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010951 }
10952 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010953 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010954 }
10955 // Invariants: at this point, the target app process exists and the application
10956 // is either already running or in the process of coming up. mBackupTarget and
10957 // mBackupAppName describe the app, so that when it binds back to the AM we
10958 // know that it's scheduled for a backup-agent operation.
10959 }
10960
10961 return true;
10962 }
10963
10964 // A backup agent has just come up
10965 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010966 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010967 + " = " + agent);
10968
10969 synchronized(this) {
10970 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010971 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010972 return;
10973 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010974 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010975
Dianne Hackborn06740692010-09-22 22:46:21 -070010976 long oldIdent = Binder.clearCallingIdentity();
10977 try {
10978 IBackupManager bm = IBackupManager.Stub.asInterface(
10979 ServiceManager.getService(Context.BACKUP_SERVICE));
10980 bm.agentConnected(agentPackageName, agent);
10981 } catch (RemoteException e) {
10982 // can't happen; the backup manager service is local
10983 } catch (Exception e) {
10984 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10985 e.printStackTrace();
10986 } finally {
10987 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010988 }
10989 }
10990
10991 // done with this agent
10992 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010993 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010994 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010995 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010996 return;
10997 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010998
10999 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011000 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011001 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011002 return;
11003 }
11004
Christopher Tate181fafa2009-05-14 11:12:14 -070011005 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011006 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011007 return;
11008 }
11009
Christopher Tate6fa95972009-06-05 18:43:55 -070011010 ProcessRecord proc = mBackupTarget.app;
11011 mBackupTarget = null;
11012 mBackupAppName = null;
11013
11014 // Not backing this app up any more; reset its OOM adjustment
11015 updateOomAdjLocked(proc);
11016
Christopher Tatec7b31e32009-06-10 15:49:30 -070011017 // If the app crashed during backup, 'thread' will be null here
11018 if (proc.thread != null) {
11019 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011020 proc.thread.scheduleDestroyBackupAgent(appInfo,
11021 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011022 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011023 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011024 e.printStackTrace();
11025 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011026 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011027 }
11028 }
11029 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011030 // BROADCASTS
11031 // =========================================================
11032
Josh Bartel7f208742010-02-25 11:01:44 -060011033 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011034 List cur) {
11035 final ContentResolver resolver = mContext.getContentResolver();
11036 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11037 if (list == null) {
11038 return cur;
11039 }
11040 int N = list.size();
11041 for (int i=0; i<N; i++) {
11042 Intent intent = list.get(i);
11043 if (filter.match(resolver, intent, true, TAG) >= 0) {
11044 if (cur == null) {
11045 cur = new ArrayList<Intent>();
11046 }
11047 cur.add(intent);
11048 }
11049 }
11050 return cur;
11051 }
11052
11053 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011054 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011055 + mBroadcastsScheduled);
11056
11057 if (mBroadcastsScheduled) {
11058 return;
11059 }
11060 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11061 mBroadcastsScheduled = true;
11062 }
11063
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011064 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011065 IIntentReceiver receiver, IntentFilter filter, String permission) {
11066 synchronized(this) {
11067 ProcessRecord callerApp = null;
11068 if (caller != null) {
11069 callerApp = getRecordForAppLocked(caller);
11070 if (callerApp == null) {
11071 throw new SecurityException(
11072 "Unable to find app for caller " + caller
11073 + " (pid=" + Binder.getCallingPid()
11074 + ") when registering receiver " + receiver);
11075 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011076 if (callerApp.info.uid != Process.SYSTEM_UID &&
11077 !callerApp.pkgList.contains(callerPackage)) {
11078 throw new SecurityException("Given caller package " + callerPackage
11079 + " is not running in process " + callerApp);
11080 }
11081 } else {
11082 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011083 }
11084
11085 List allSticky = null;
11086
11087 // Look for any matching sticky broadcasts...
11088 Iterator actions = filter.actionsIterator();
11089 if (actions != null) {
11090 while (actions.hasNext()) {
11091 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011092 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011093 }
11094 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011095 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011096 }
11097
11098 // The first sticky in the list is returned directly back to
11099 // the client.
11100 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11101
Joe Onorato8a9b2202010-02-26 18:56:32 -080011102 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011103 + ": " + sticky);
11104
11105 if (receiver == null) {
11106 return sticky;
11107 }
11108
11109 ReceiverList rl
11110 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11111 if (rl == null) {
11112 rl = new ReceiverList(this, callerApp,
11113 Binder.getCallingPid(),
11114 Binder.getCallingUid(), receiver);
11115 if (rl.app != null) {
11116 rl.app.receivers.add(rl);
11117 } else {
11118 try {
11119 receiver.asBinder().linkToDeath(rl, 0);
11120 } catch (RemoteException e) {
11121 return sticky;
11122 }
11123 rl.linkedToDeath = true;
11124 }
11125 mRegisteredReceivers.put(receiver.asBinder(), rl);
11126 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011127 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011128 rl.add(bf);
11129 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011130 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011131 }
11132 mReceiverResolver.addFilter(bf);
11133
11134 // Enqueue broadcasts for all existing stickies that match
11135 // this filter.
11136 if (allSticky != null) {
11137 ArrayList receivers = new ArrayList();
11138 receivers.add(bf);
11139
11140 int N = allSticky.size();
11141 for (int i=0; i<N; i++) {
11142 Intent intent = (Intent)allSticky.get(i);
11143 BroadcastRecord r = new BroadcastRecord(intent, null,
11144 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011145 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011146 if (mParallelBroadcasts.size() == 0) {
11147 scheduleBroadcastsLocked();
11148 }
11149 mParallelBroadcasts.add(r);
11150 }
11151 }
11152
11153 return sticky;
11154 }
11155 }
11156
11157 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011158 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011159
11160 boolean doNext = false;
11161
11162 synchronized(this) {
11163 ReceiverList rl
11164 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11165 if (rl != null) {
11166 if (rl.curBroadcast != null) {
11167 BroadcastRecord r = rl.curBroadcast;
11168 doNext = finishReceiverLocked(
11169 receiver.asBinder(), r.resultCode, r.resultData,
11170 r.resultExtras, r.resultAbort, true);
11171 }
11172
11173 if (rl.app != null) {
11174 rl.app.receivers.remove(rl);
11175 }
11176 removeReceiverLocked(rl);
11177 if (rl.linkedToDeath) {
11178 rl.linkedToDeath = false;
11179 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11180 }
11181 }
11182 }
11183
11184 if (!doNext) {
11185 return;
11186 }
11187
11188 final long origId = Binder.clearCallingIdentity();
11189 processNextBroadcast(false);
11190 trimApplications();
11191 Binder.restoreCallingIdentity(origId);
11192 }
11193
11194 void removeReceiverLocked(ReceiverList rl) {
11195 mRegisteredReceivers.remove(rl.receiver.asBinder());
11196 int N = rl.size();
11197 for (int i=0; i<N; i++) {
11198 mReceiverResolver.removeFilter(rl.get(i));
11199 }
11200 }
11201
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011202 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11203 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11204 ProcessRecord r = mLruProcesses.get(i);
11205 if (r.thread != null) {
11206 try {
11207 r.thread.dispatchPackageBroadcast(cmd, packages);
11208 } catch (RemoteException ex) {
11209 }
11210 }
11211 }
11212 }
11213
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011214 private final int broadcastIntentLocked(ProcessRecord callerApp,
11215 String callerPackage, Intent intent, String resolvedType,
11216 IIntentReceiver resultTo, int resultCode, String resultData,
11217 Bundle map, String requiredPermission,
11218 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11219 intent = new Intent(intent);
11220
Dianne Hackborne7f97212011-02-24 14:40:20 -080011221 // By default broadcasts do not go to stopped apps.
11222 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11223
Joe Onorato8a9b2202010-02-26 18:56:32 -080011224 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011225 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11226 + " ordered=" + ordered);
11227 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011228 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011229 }
11230
11231 // Handle special intents: if this broadcast is from the package
11232 // manager about a package being removed, we need to remove all of
11233 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011234 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011235 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011236 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11237 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011238 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011239 || uidRemoved) {
11240 if (checkComponentPermission(
11241 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011242 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011243 == PackageManager.PERMISSION_GRANTED) {
11244 if (uidRemoved) {
11245 final Bundle intentExtras = intent.getExtras();
11246 final int uid = intentExtras != null
11247 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11248 if (uid >= 0) {
11249 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11250 synchronized (bs) {
11251 bs.removeUidStatsLocked(uid);
11252 }
11253 }
11254 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011255 // If resources are unvailble just force stop all
11256 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011257 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011258 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11259 if (list != null && (list.length > 0)) {
11260 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011261 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011262 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011263 sendPackageBroadcastLocked(
11264 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011265 }
11266 } else {
11267 Uri data = intent.getData();
11268 String ssp;
11269 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11270 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11271 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011272 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011273 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011274 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011275 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11276 new String[] {ssp});
11277 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011278 }
11279 }
11280 }
11281 } else {
11282 String msg = "Permission Denial: " + intent.getAction()
11283 + " broadcast from " + callerPackage + " (pid=" + callingPid
11284 + ", uid=" + callingUid + ")"
11285 + " requires "
11286 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011287 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011288 throw new SecurityException(msg);
11289 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011290
11291 // Special case for adding a package: by default turn on compatibility
11292 // mode.
11293 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011294 Uri data = intent.getData();
11295 String ssp;
11296 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11297 mCompatModePackages.handlePackageAddedLocked(ssp,
11298 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011300 }
11301
11302 /*
11303 * If this is the time zone changed action, queue up a message that will reset the timezone
11304 * of all currently running processes. This message will get queued up before the broadcast
11305 * happens.
11306 */
11307 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11308 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11309 }
11310
Robert Greenwalt03595d02010-11-02 14:08:23 -070011311 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11312 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11313 }
11314
Robert Greenwalt434203a2010-10-11 16:00:27 -070011315 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11316 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11317 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11318 }
11319
Dianne Hackborn854060af2009-07-09 18:14:31 -070011320 /*
11321 * Prevent non-system code (defined here to be non-persistent
11322 * processes) from sending protected broadcasts.
11323 */
11324 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11325 || callingUid == Process.SHELL_UID || callingUid == 0) {
11326 // Always okay.
11327 } else if (callerApp == null || !callerApp.persistent) {
11328 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011329 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011330 intent.getAction())) {
11331 String msg = "Permission Denial: not allowed to send broadcast "
11332 + intent.getAction() + " from pid="
11333 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011334 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011335 throw new SecurityException(msg);
11336 }
11337 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011338 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011339 return BROADCAST_SUCCESS;
11340 }
11341 }
11342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011343 // Add to the sticky list if requested.
11344 if (sticky) {
11345 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11346 callingPid, callingUid)
11347 != PackageManager.PERMISSION_GRANTED) {
11348 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11349 + callingPid + ", uid=" + callingUid
11350 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011351 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011352 throw new SecurityException(msg);
11353 }
11354 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011355 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011356 + " and enforce permission " + requiredPermission);
11357 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11358 }
11359 if (intent.getComponent() != null) {
11360 throw new SecurityException(
11361 "Sticky broadcasts can't target a specific component");
11362 }
11363 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11364 if (list == null) {
11365 list = new ArrayList<Intent>();
11366 mStickyBroadcasts.put(intent.getAction(), list);
11367 }
11368 int N = list.size();
11369 int i;
11370 for (i=0; i<N; i++) {
11371 if (intent.filterEquals(list.get(i))) {
11372 // This sticky already exists, replace it.
11373 list.set(i, new Intent(intent));
11374 break;
11375 }
11376 }
11377 if (i >= N) {
11378 list.add(new Intent(intent));
11379 }
11380 }
11381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011382 // Figure out who all will receive this broadcast.
11383 List receivers = null;
11384 List<BroadcastFilter> registeredReceivers = null;
11385 try {
11386 if (intent.getComponent() != null) {
11387 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011388 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011389 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011390 if (ai != null) {
11391 receivers = new ArrayList();
11392 ResolveInfo ri = new ResolveInfo();
11393 ri.activityInfo = ai;
11394 receivers.add(ri);
11395 }
11396 } else {
11397 // Need to resolve the intent to interested receivers...
11398 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11399 == 0) {
11400 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011401 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011402 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011403 }
Mihai Preda074edef2009-05-18 17:13:31 +020011404 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011405 }
11406 } catch (RemoteException ex) {
11407 // pm is in same process, this will never happen.
11408 }
11409
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011410 final boolean replacePending =
11411 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11412
Joe Onorato8a9b2202010-02-26 18:56:32 -080011413 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011414 + " replacePending=" + replacePending);
11415
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11417 if (!ordered && NR > 0) {
11418 // If we are not serializing this broadcast, then send the
11419 // registered receivers separately so they don't wait for the
11420 // components to be launched.
11421 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11422 callerPackage, callingPid, callingUid, requiredPermission,
11423 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011424 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011425 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011426 TAG, "Enqueueing parallel broadcast " + r
11427 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011428 boolean replaced = false;
11429 if (replacePending) {
11430 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11431 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011432 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011433 "***** DROPPING PARALLEL: " + intent);
11434 mParallelBroadcasts.set(i, r);
11435 replaced = true;
11436 break;
11437 }
11438 }
11439 }
11440 if (!replaced) {
11441 mParallelBroadcasts.add(r);
11442 scheduleBroadcastsLocked();
11443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011444 registeredReceivers = null;
11445 NR = 0;
11446 }
11447
11448 // Merge into one list.
11449 int ir = 0;
11450 if (receivers != null) {
11451 // A special case for PACKAGE_ADDED: do not allow the package
11452 // being added to see this broadcast. This prevents them from
11453 // using this as a back door to get run as soon as they are
11454 // installed. Maybe in the future we want to have a special install
11455 // broadcast or such for apps, but we'd like to deliberately make
11456 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011457 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011458 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11459 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11460 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011461 Uri data = intent.getData();
11462 if (data != null) {
11463 String pkgName = data.getSchemeSpecificPart();
11464 if (pkgName != null) {
11465 skipPackages = new String[] { pkgName };
11466 }
11467 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011468 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011469 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011470 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011471 if (skipPackages != null && (skipPackages.length > 0)) {
11472 for (String skipPackage : skipPackages) {
11473 if (skipPackage != null) {
11474 int NT = receivers.size();
11475 for (int it=0; it<NT; it++) {
11476 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11477 if (curt.activityInfo.packageName.equals(skipPackage)) {
11478 receivers.remove(it);
11479 it--;
11480 NT--;
11481 }
11482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011483 }
11484 }
11485 }
11486
11487 int NT = receivers != null ? receivers.size() : 0;
11488 int it = 0;
11489 ResolveInfo curt = null;
11490 BroadcastFilter curr = null;
11491 while (it < NT && ir < NR) {
11492 if (curt == null) {
11493 curt = (ResolveInfo)receivers.get(it);
11494 }
11495 if (curr == null) {
11496 curr = registeredReceivers.get(ir);
11497 }
11498 if (curr.getPriority() >= curt.priority) {
11499 // Insert this broadcast record into the final list.
11500 receivers.add(it, curr);
11501 ir++;
11502 curr = null;
11503 it++;
11504 NT++;
11505 } else {
11506 // Skip to the next ResolveInfo in the final list.
11507 it++;
11508 curt = null;
11509 }
11510 }
11511 }
11512 while (ir < NR) {
11513 if (receivers == null) {
11514 receivers = new ArrayList();
11515 }
11516 receivers.add(registeredReceivers.get(ir));
11517 ir++;
11518 }
11519
11520 if ((receivers != null && receivers.size() > 0)
11521 || resultTo != null) {
11522 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11523 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011524 receivers, resultTo, resultCode, resultData, map, ordered,
11525 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011526 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011527 TAG, "Enqueueing ordered broadcast " + r
11528 + ": prev had " + mOrderedBroadcasts.size());
11529 if (DEBUG_BROADCAST) {
11530 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011531 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011532 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011533 boolean replaced = false;
11534 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011535 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011536 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011537 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011538 "***** DROPPING ORDERED: " + intent);
11539 mOrderedBroadcasts.set(i, r);
11540 replaced = true;
11541 break;
11542 }
11543 }
11544 }
11545 if (!replaced) {
11546 mOrderedBroadcasts.add(r);
11547 scheduleBroadcastsLocked();
11548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011549 }
11550
11551 return BROADCAST_SUCCESS;
11552 }
11553
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011554 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011555 // Refuse possible leaked file descriptors
11556 if (intent != null && intent.hasFileDescriptors() == true) {
11557 throw new IllegalArgumentException("File descriptors passed in Intent");
11558 }
11559
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011560 int flags = intent.getFlags();
11561
11562 if (!mProcessesReady) {
11563 // if the caller really truly claims to know what they're doing, go
11564 // ahead and allow the broadcast without launching any receivers
11565 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11566 intent = new Intent(intent);
11567 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11568 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11569 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11570 + " before boot completion");
11571 throw new IllegalStateException("Cannot broadcast before boot completed");
11572 }
11573 }
11574
11575 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11576 throw new IllegalArgumentException(
11577 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11578 }
11579
11580 return intent;
11581 }
11582
11583 public final int broadcastIntent(IApplicationThread caller,
11584 Intent intent, String resolvedType, IIntentReceiver resultTo,
11585 int resultCode, String resultData, Bundle map,
11586 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011588 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011590 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11591 final int callingPid = Binder.getCallingPid();
11592 final int callingUid = Binder.getCallingUid();
11593 final long origId = Binder.clearCallingIdentity();
11594 int res = broadcastIntentLocked(callerApp,
11595 callerApp != null ? callerApp.info.packageName : null,
11596 intent, resolvedType, resultTo,
11597 resultCode, resultData, map, requiredPermission, serialized,
11598 sticky, callingPid, callingUid);
11599 Binder.restoreCallingIdentity(origId);
11600 return res;
11601 }
11602 }
11603
11604 int broadcastIntentInPackage(String packageName, int uid,
11605 Intent intent, String resolvedType, IIntentReceiver resultTo,
11606 int resultCode, String resultData, Bundle map,
11607 String requiredPermission, boolean serialized, boolean sticky) {
11608 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011609 intent = verifyBroadcastLocked(intent);
11610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011611 final long origId = Binder.clearCallingIdentity();
11612 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11613 resultTo, resultCode, resultData, map, requiredPermission,
11614 serialized, sticky, -1, uid);
11615 Binder.restoreCallingIdentity(origId);
11616 return res;
11617 }
11618 }
11619
11620 public final void unbroadcastIntent(IApplicationThread caller,
11621 Intent intent) {
11622 // Refuse possible leaked file descriptors
11623 if (intent != null && intent.hasFileDescriptors() == true) {
11624 throw new IllegalArgumentException("File descriptors passed in Intent");
11625 }
11626
11627 synchronized(this) {
11628 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11629 != PackageManager.PERMISSION_GRANTED) {
11630 String msg = "Permission Denial: unbroadcastIntent() from pid="
11631 + Binder.getCallingPid()
11632 + ", uid=" + Binder.getCallingUid()
11633 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011634 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011635 throw new SecurityException(msg);
11636 }
11637 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11638 if (list != null) {
11639 int N = list.size();
11640 int i;
11641 for (i=0; i<N; i++) {
11642 if (intent.filterEquals(list.get(i))) {
11643 list.remove(i);
11644 break;
11645 }
11646 }
11647 }
11648 }
11649 }
11650
11651 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11652 String resultData, Bundle resultExtras, boolean resultAbort,
11653 boolean explicit) {
11654 if (mOrderedBroadcasts.size() == 0) {
11655 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011656 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011657 }
11658 return false;
11659 }
11660 BroadcastRecord r = mOrderedBroadcasts.get(0);
11661 if (r.receiver == null) {
11662 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011663 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011664 }
11665 return false;
11666 }
11667 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011668 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011669 return false;
11670 }
11671 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011672 r.state = BroadcastRecord.IDLE;
11673 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011675 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011676 }
11677 }
11678 r.receiver = null;
11679 r.intent.setComponent(null);
11680 if (r.curApp != null) {
11681 r.curApp.curReceiver = null;
11682 }
11683 if (r.curFilter != null) {
11684 r.curFilter.receiverList.curBroadcast = null;
11685 }
11686 r.curFilter = null;
11687 r.curApp = null;
11688 r.curComponent = null;
11689 r.curReceiver = null;
11690 mPendingBroadcast = null;
11691
11692 r.resultCode = resultCode;
11693 r.resultData = resultData;
11694 r.resultExtras = resultExtras;
11695 r.resultAbort = resultAbort;
11696
11697 // We will process the next receiver right now if this is finishing
11698 // an app receiver (which is always asynchronous) or after we have
11699 // come back from calling a receiver.
11700 return state == BroadcastRecord.APP_RECEIVE
11701 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11702 }
11703
11704 public void finishReceiver(IBinder who, int resultCode, String resultData,
11705 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011706 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011707
11708 // Refuse possible leaked file descriptors
11709 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11710 throw new IllegalArgumentException("File descriptors passed in Bundle");
11711 }
11712
11713 boolean doNext;
11714
11715 final long origId = Binder.clearCallingIdentity();
11716
11717 synchronized(this) {
11718 doNext = finishReceiverLocked(
11719 who, resultCode, resultData, resultExtras, resultAbort, true);
11720 }
11721
11722 if (doNext) {
11723 processNextBroadcast(false);
11724 }
11725 trimApplications();
11726
11727 Binder.restoreCallingIdentity(origId);
11728 }
11729
Jeff Brown4d94a762010-09-23 11:33:28 -070011730 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011731 if (r.nextReceiver > 0) {
11732 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11733 if (curReceiver instanceof BroadcastFilter) {
11734 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011735 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011736 System.identityHashCode(r),
11737 r.intent.getAction(),
11738 r.nextReceiver - 1,
11739 System.identityHashCode(bf));
11740 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011741 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011742 System.identityHashCode(r),
11743 r.intent.getAction(),
11744 r.nextReceiver - 1,
11745 ((ResolveInfo)curReceiver).toString());
11746 }
11747 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011748 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011749 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011750 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011751 System.identityHashCode(r),
11752 r.intent.getAction(),
11753 r.nextReceiver,
11754 "NONE");
11755 }
11756 }
11757
Jeff Brown4d94a762010-09-23 11:33:28 -070011758 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11759 if (! mPendingBroadcastTimeoutMessage) {
11760 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11761 mHandler.sendMessageAtTime(msg, timeoutTime);
11762 mPendingBroadcastTimeoutMessage = true;
11763 }
11764 }
11765
11766 private final void cancelBroadcastTimeoutLocked() {
11767 if (mPendingBroadcastTimeoutMessage) {
11768 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11769 mPendingBroadcastTimeoutMessage = false;
11770 }
11771 }
11772
11773 private final void broadcastTimeoutLocked(boolean fromMsg) {
11774 if (fromMsg) {
11775 mPendingBroadcastTimeoutMessage = false;
11776 }
11777
11778 if (mOrderedBroadcasts.size() == 0) {
11779 return;
11780 }
11781
11782 long now = SystemClock.uptimeMillis();
11783 BroadcastRecord r = mOrderedBroadcasts.get(0);
11784 if (fromMsg) {
11785 if (mDidDexOpt) {
11786 // Delay timeouts until dexopt finishes.
11787 mDidDexOpt = false;
11788 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11789 setBroadcastTimeoutLocked(timeoutTime);
11790 return;
11791 }
11792 if (! mProcessesReady) {
11793 // Only process broadcast timeouts if the system is ready. That way
11794 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11795 // to do heavy lifting for system up.
11796 return;
11797 }
11798
11799 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11800 if (timeoutTime > now) {
11801 // We can observe premature timeouts because we do not cancel and reset the
11802 // broadcast timeout message after each receiver finishes. Instead, we set up
11803 // an initial timeout then kick it down the road a little further as needed
11804 // when it expires.
11805 if (DEBUG_BROADCAST) Slog.v(TAG,
11806 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11807 + timeoutTime);
11808 setBroadcastTimeoutLocked(timeoutTime);
11809 return;
11810 }
11811 }
11812
11813 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11814 + ", started " + (now - r.receiverTime) + "ms ago");
11815 r.receiverTime = now;
11816 r.anrCount++;
11817
11818 // Current receiver has passed its expiration date.
11819 if (r.nextReceiver <= 0) {
11820 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11821 return;
11822 }
11823
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011824 ProcessRecord app = null;
11825 String anrMessage = null;
11826
Jeff Brown4d94a762010-09-23 11:33:28 -070011827 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11828 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
11829 logBroadcastReceiverDiscardLocked(r);
11830 if (curReceiver instanceof BroadcastFilter) {
11831 BroadcastFilter bf = (BroadcastFilter)curReceiver;
11832 if (bf.receiverList.pid != 0
11833 && bf.receiverList.pid != MY_PID) {
11834 synchronized (this.mPidsSelfLocked) {
11835 app = this.mPidsSelfLocked.get(
11836 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011838 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011839 } else {
11840 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011842
Jeff Brown4d94a762010-09-23 11:33:28 -070011843 if (app != null) {
11844 anrMessage = "Broadcast of " + r.intent.toString();
11845 }
11846
11847 if (mPendingBroadcast == r) {
11848 mPendingBroadcast = null;
11849 }
11850
11851 // Move on to the next receiver.
11852 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
11853 r.resultExtras, r.resultAbort, true);
11854 scheduleBroadcastsLocked();
11855
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011856 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070011857 // Post the ANR to the handler since we do not want to process ANRs while
11858 // potentially holding our lock.
11859 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011860 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011861 }
11862
11863 private final void processCurBroadcastLocked(BroadcastRecord r,
11864 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011865 if (DEBUG_BROADCAST) Slog.v(TAG,
11866 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 if (app.thread == null) {
11868 throw new RemoteException();
11869 }
11870 r.receiver = app.thread.asBinder();
11871 r.curApp = app;
11872 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011873 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011874
11875 // Tell the application to launch this receiver.
11876 r.intent.setComponent(r.curComponent);
11877
11878 boolean started = false;
11879 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011880 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011881 "Delivering to component " + r.curComponent
11882 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011883 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011884 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011885 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011886 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011887 if (DEBUG_BROADCAST) Slog.v(TAG,
11888 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011889 started = true;
11890 } finally {
11891 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011892 if (DEBUG_BROADCAST) Slog.v(TAG,
11893 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011894 r.receiver = null;
11895 r.curApp = null;
11896 app.curReceiver = null;
11897 }
11898 }
11899
11900 }
11901
Jeff Brown4d94a762010-09-23 11:33:28 -070011902 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011903 Intent intent, int resultCode, String data, Bundle extras,
11904 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070011905 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011906 if (app != null && app.thread != null) {
11907 // If we have an app thread, do the call through that so it is
11908 // correctly ordered with other one-way calls.
11909 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011910 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011911 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070011912 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011913 }
11914 }
11915
Jeff Brown4d94a762010-09-23 11:33:28 -070011916 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011917 BroadcastFilter filter, boolean ordered) {
11918 boolean skip = false;
11919 if (filter.requiredPermission != null) {
11920 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011921 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011922 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011923 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011924 + r.intent.toString()
11925 + " from " + r.callerPackage + " (pid="
11926 + r.callingPid + ", uid=" + r.callingUid + ")"
11927 + " requires " + filter.requiredPermission
11928 + " due to registered receiver " + filter);
11929 skip = true;
11930 }
11931 }
11932 if (r.requiredPermission != null) {
11933 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011934 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011935 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011936 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011937 + r.intent.toString()
11938 + " to " + filter.receiverList.app
11939 + " (pid=" + filter.receiverList.pid
11940 + ", uid=" + filter.receiverList.uid + ")"
11941 + " requires " + r.requiredPermission
11942 + " due to sender " + r.callerPackage
11943 + " (uid " + r.callingUid + ")");
11944 skip = true;
11945 }
11946 }
11947
11948 if (!skip) {
11949 // If this is not being sent as an ordered broadcast, then we
11950 // don't want to touch the fields that keep track of the current
11951 // state of ordered broadcasts.
11952 if (ordered) {
11953 r.receiver = filter.receiverList.receiver.asBinder();
11954 r.curFilter = filter;
11955 filter.receiverList.curBroadcast = r;
11956 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011957 if (filter.receiverList.app != null) {
11958 // Bump hosting application to no longer be in background
11959 // scheduling class. Note that we can't do that if there
11960 // isn't an app... but we can only be in that case for
11961 // things that directly call the IActivityManager API, which
11962 // are already core system stuff so don't matter for this.
11963 r.curApp = filter.receiverList.app;
11964 filter.receiverList.app.curReceiver = r;
11965 updateOomAdjLocked();
11966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011967 }
11968 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011969 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011970 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070011971 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011972 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011973 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011974 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011975 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011976 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011977 if (ordered) {
11978 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
11979 }
11980 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011981 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011982 if (ordered) {
11983 r.receiver = null;
11984 r.curFilter = null;
11985 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070011986 if (filter.receiverList.app != null) {
11987 filter.receiverList.app.curReceiver = null;
11988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011989 }
11990 }
11991 }
11992 }
11993
Dianne Hackborn12527f92009-11-11 17:39:50 -080011994 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
11995 if (r.callingUid < 0) {
11996 // This was from a registerReceiver() call; ignore it.
11997 return;
11998 }
11999 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12000 MAX_BROADCAST_HISTORY-1);
12001 r.finishTime = SystemClock.uptimeMillis();
12002 mBroadcastHistory[0] = r;
12003 }
12004
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012005 private final void processNextBroadcast(boolean fromMsg) {
12006 synchronized(this) {
12007 BroadcastRecord r;
12008
Joe Onorato8a9b2202010-02-26 18:56:32 -080012009 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012010 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012011 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012012
12013 updateCpuStats();
12014
12015 if (fromMsg) {
12016 mBroadcastsScheduled = false;
12017 }
12018
12019 // First, deliver any non-serialized broadcasts right away.
12020 while (mParallelBroadcasts.size() > 0) {
12021 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012022 r.dispatchTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012023 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012024 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012025 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012026 for (int i=0; i<N; i++) {
12027 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012028 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012029 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012030 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012031 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012032 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012033 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012034 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012035 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012036 }
12037
12038 // Now take care of the next serialized one...
12039
12040 // If we are waiting for a process to come up to handle the next
12041 // broadcast, then do nothing at this point. Just in case, we
12042 // check that the process we're waiting for still exists.
12043 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012044 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012045 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012046 + mPendingBroadcast.curApp);
12047 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012048
12049 boolean isDead;
12050 synchronized (mPidsSelfLocked) {
12051 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12052 }
12053 if (!isDead) {
12054 // It's still alive, so keep waiting
12055 return;
12056 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012057 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012059 mPendingBroadcast.state = BroadcastRecord.IDLE;
12060 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 mPendingBroadcast = null;
12062 }
12063 }
12064
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012065 boolean looped = false;
12066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012067 do {
12068 if (mOrderedBroadcasts.size() == 0) {
12069 // No more broadcasts pending, so all done!
12070 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012071 if (looped) {
12072 // If we had finished the last ordered broadcast, then
12073 // make sure all processes have correct oom and sched
12074 // adjustments.
12075 updateOomAdjLocked();
12076 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012077 return;
12078 }
12079 r = mOrderedBroadcasts.get(0);
12080 boolean forceReceive = false;
12081
12082 // Ensure that even if something goes awry with the timeout
12083 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012084 // and continue to make progress.
12085 //
12086 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012087 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012088 // one time heavy lifting after system upgrades and can take
12089 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012090 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012091 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012092 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012093 if ((numReceivers > 0) &&
12094 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012095 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012096 + " now=" + now
12097 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012098 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012099 + " intent=" + r.intent
12100 + " numReceivers=" + numReceivers
12101 + " nextReceiver=" + r.nextReceiver
12102 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012103 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012104 forceReceive = true;
12105 r.state = BroadcastRecord.IDLE;
12106 }
12107 }
12108
12109 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012110 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012111 "processNextBroadcast() called when not idle (state="
12112 + r.state + ")");
12113 return;
12114 }
12115
12116 if (r.receivers == null || r.nextReceiver >= numReceivers
12117 || r.resultAbort || forceReceive) {
12118 // No more receivers for this broadcast! Send the final
12119 // result if requested...
12120 if (r.resultTo != null) {
12121 try {
12122 if (DEBUG_BROADCAST) {
12123 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012124 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012125 + " seq=" + seq + " app=" + r.callerApp);
12126 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012127 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012128 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012129 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012130 // Set this to null so that the reference
12131 // (local and remote) isnt kept in the mBroadcastHistory.
12132 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012133 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012134 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012135 }
12136 }
12137
Joe Onorato8a9b2202010-02-26 18:56:32 -080012138 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012139 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012140
Joe Onorato8a9b2202010-02-26 18:56:32 -080012141 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012142 + r);
12143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012144 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012145 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012146 mOrderedBroadcasts.remove(0);
12147 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012148 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 continue;
12150 }
12151 } while (r == null);
12152
12153 // Get the next receiver...
12154 int recIdx = r.nextReceiver++;
12155
12156 // Keep track of when this receiver started, and make sure there
12157 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012158 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012159 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012160 r.dispatchTime = r.receiverTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012161
Joe Onorato8a9b2202010-02-26 18:56:32 -080012162 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012163 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012164 }
12165 if (! mPendingBroadcastTimeoutMessage) {
12166 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012167 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012168 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12169 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012170 }
12171
12172 Object nextReceiver = r.receivers.get(recIdx);
12173 if (nextReceiver instanceof BroadcastFilter) {
12174 // Simple case: this is a registered receiver who gets
12175 // a direct call.
12176 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012177 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012178 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012179 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012180 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012181 if (r.receiver == null || !r.ordered) {
12182 // The receiver has already finished, so schedule to
12183 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012184 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12185 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012186 r.state = BroadcastRecord.IDLE;
12187 scheduleBroadcastsLocked();
12188 }
12189 return;
12190 }
12191
12192 // Hard case: need to instantiate the receiver, possibly
12193 // starting its application process to host it.
12194
12195 ResolveInfo info =
12196 (ResolveInfo)nextReceiver;
12197
12198 boolean skip = false;
12199 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012200 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12201 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012202 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012203 if (!info.activityInfo.exported) {
12204 Slog.w(TAG, "Permission Denial: broadcasting "
12205 + r.intent.toString()
12206 + " from " + r.callerPackage + " (pid=" + r.callingPid
12207 + ", uid=" + r.callingUid + ")"
12208 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12209 + " due to receiver " + info.activityInfo.packageName
12210 + "/" + info.activityInfo.name);
12211 } else {
12212 Slog.w(TAG, "Permission Denial: broadcasting "
12213 + r.intent.toString()
12214 + " from " + r.callerPackage + " (pid=" + r.callingPid
12215 + ", uid=" + r.callingUid + ")"
12216 + " requires " + info.activityInfo.permission
12217 + " due to receiver " + info.activityInfo.packageName
12218 + "/" + info.activityInfo.name);
12219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012220 skip = true;
12221 }
12222 if (r.callingUid != Process.SYSTEM_UID &&
12223 r.requiredPermission != null) {
12224 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012225 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012226 checkPermission(r.requiredPermission,
12227 info.activityInfo.applicationInfo.packageName);
12228 } catch (RemoteException e) {
12229 perm = PackageManager.PERMISSION_DENIED;
12230 }
12231 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012232 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012233 + r.intent + " to "
12234 + info.activityInfo.applicationInfo.packageName
12235 + " requires " + r.requiredPermission
12236 + " due to sender " + r.callerPackage
12237 + " (uid " + r.callingUid + ")");
12238 skip = true;
12239 }
12240 }
12241 if (r.curApp != null && r.curApp.crashing) {
12242 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012243 if (DEBUG_BROADCAST) Slog.v(TAG,
12244 "Skipping deliver ordered " + r + " to " + r.curApp
12245 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 skip = true;
12247 }
12248
12249 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012250 if (DEBUG_BROADCAST) Slog.v(TAG,
12251 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012252 r.receiver = null;
12253 r.curFilter = null;
12254 r.state = BroadcastRecord.IDLE;
12255 scheduleBroadcastsLocked();
12256 return;
12257 }
12258
12259 r.state = BroadcastRecord.APP_RECEIVE;
12260 String targetProcess = info.activityInfo.processName;
12261 r.curComponent = new ComponentName(
12262 info.activityInfo.applicationInfo.packageName,
12263 info.activityInfo.name);
12264 r.curReceiver = info.activityInfo;
12265
Dianne Hackborne7f97212011-02-24 14:40:20 -080012266 // Broadcast is being executed, its package can't be stopped.
12267 try {
12268 AppGlobals.getPackageManager().setPackageStoppedState(
12269 r.curComponent.getPackageName(), false);
12270 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012271 } catch (IllegalArgumentException e) {
12272 Slog.w(TAG, "Failed trying to unstop package "
12273 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012274 }
12275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012276 // Is this receiver's application already running?
12277 ProcessRecord app = getProcessRecordLocked(targetProcess,
12278 info.activityInfo.applicationInfo.uid);
12279 if (app != null && app.thread != null) {
12280 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012281 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012282 processCurBroadcastLocked(r, app);
12283 return;
12284 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012285 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012286 + r.curComponent, e);
12287 }
12288
12289 // If a dead object exception was thrown -- fall through to
12290 // restart the application.
12291 }
12292
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012293 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012294 if (DEBUG_BROADCAST) Slog.v(TAG,
12295 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012296 if ((r.curApp=startProcessLocked(targetProcess,
12297 info.activityInfo.applicationInfo, true,
12298 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012299 "broadcast", r.curComponent,
12300 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12301 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012302 // Ah, this recipient is unavailable. Finish it if necessary,
12303 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012304 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012305 + info.activityInfo.applicationInfo.packageName + "/"
12306 + info.activityInfo.applicationInfo.uid + " for broadcast "
12307 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012308 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012309 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12310 r.resultExtras, r.resultAbort, true);
12311 scheduleBroadcastsLocked();
12312 r.state = BroadcastRecord.IDLE;
12313 return;
12314 }
12315
12316 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012317 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012318 }
12319 }
12320
12321 // =========================================================
12322 // INSTRUMENTATION
12323 // =========================================================
12324
12325 public boolean startInstrumentation(ComponentName className,
12326 String profileFile, int flags, Bundle arguments,
12327 IInstrumentationWatcher watcher) {
12328 // Refuse possible leaked file descriptors
12329 if (arguments != null && arguments.hasFileDescriptors()) {
12330 throw new IllegalArgumentException("File descriptors passed in Bundle");
12331 }
12332
12333 synchronized(this) {
12334 InstrumentationInfo ii = null;
12335 ApplicationInfo ai = null;
12336 try {
12337 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012338 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012339 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012340 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012341 } catch (PackageManager.NameNotFoundException e) {
12342 }
12343 if (ii == null) {
12344 reportStartInstrumentationFailure(watcher, className,
12345 "Unable to find instrumentation info for: " + className);
12346 return false;
12347 }
12348 if (ai == null) {
12349 reportStartInstrumentationFailure(watcher, className,
12350 "Unable to find instrumentation target package: " + ii.targetPackage);
12351 return false;
12352 }
12353
12354 int match = mContext.getPackageManager().checkSignatures(
12355 ii.targetPackage, ii.packageName);
12356 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12357 String msg = "Permission Denial: starting instrumentation "
12358 + className + " from pid="
12359 + Binder.getCallingPid()
12360 + ", uid=" + Binder.getCallingPid()
12361 + " not allowed because package " + ii.packageName
12362 + " does not have a signature matching the target "
12363 + ii.targetPackage;
12364 reportStartInstrumentationFailure(watcher, className, msg);
12365 throw new SecurityException(msg);
12366 }
12367
12368 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012369 // Instrumentation can kill and relaunch even persistent processes
12370 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012371 ProcessRecord app = addAppLocked(ai);
12372 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012373 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 app.instrumentationProfileFile = profileFile;
12375 app.instrumentationArguments = arguments;
12376 app.instrumentationWatcher = watcher;
12377 app.instrumentationResultClass = className;
12378 Binder.restoreCallingIdentity(origId);
12379 }
12380
12381 return true;
12382 }
12383
12384 /**
12385 * Report errors that occur while attempting to start Instrumentation. Always writes the
12386 * error to the logs, but if somebody is watching, send the report there too. This enables
12387 * the "am" command to report errors with more information.
12388 *
12389 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12390 * @param cn The component name of the instrumentation.
12391 * @param report The error report.
12392 */
12393 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12394 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012395 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012396 try {
12397 if (watcher != null) {
12398 Bundle results = new Bundle();
12399 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12400 results.putString("Error", report);
12401 watcher.instrumentationStatus(cn, -1, results);
12402 }
12403 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012404 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012405 }
12406 }
12407
12408 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12409 if (app.instrumentationWatcher != null) {
12410 try {
12411 // NOTE: IInstrumentationWatcher *must* be oneway here
12412 app.instrumentationWatcher.instrumentationFinished(
12413 app.instrumentationClass,
12414 resultCode,
12415 results);
12416 } catch (RemoteException e) {
12417 }
12418 }
12419 app.instrumentationWatcher = null;
12420 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012421 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012422 app.instrumentationProfileFile = null;
12423 app.instrumentationArguments = null;
12424
Christopher Tate3dacd842011-08-19 14:56:15 -070012425 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012426 }
12427
12428 public void finishInstrumentation(IApplicationThread target,
12429 int resultCode, Bundle results) {
12430 // Refuse possible leaked file descriptors
12431 if (results != null && results.hasFileDescriptors()) {
12432 throw new IllegalArgumentException("File descriptors passed in Intent");
12433 }
12434
12435 synchronized(this) {
12436 ProcessRecord app = getRecordForAppLocked(target);
12437 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012438 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012439 return;
12440 }
12441 final long origId = Binder.clearCallingIdentity();
12442 finishInstrumentationLocked(app, resultCode, results);
12443 Binder.restoreCallingIdentity(origId);
12444 }
12445 }
12446
12447 // =========================================================
12448 // CONFIGURATION
12449 // =========================================================
12450
12451 public ConfigurationInfo getDeviceConfigurationInfo() {
12452 ConfigurationInfo config = new ConfigurationInfo();
12453 synchronized (this) {
12454 config.reqTouchScreen = mConfiguration.touchscreen;
12455 config.reqKeyboardType = mConfiguration.keyboard;
12456 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012457 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12458 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12460 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012461 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12462 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012463 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12464 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012465 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012466 }
12467 return config;
12468 }
12469
12470 public Configuration getConfiguration() {
12471 Configuration ci;
12472 synchronized(this) {
12473 ci = new Configuration(mConfiguration);
12474 }
12475 return ci;
12476 }
12477
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012478 public void updatePersistentConfiguration(Configuration values) {
12479 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12480 "updateConfiguration()");
12481 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12482 "updateConfiguration()");
12483 if (values == null) {
12484 throw new NullPointerException("Configuration must not be null");
12485 }
12486
12487 synchronized(this) {
12488 final long origId = Binder.clearCallingIdentity();
12489 updateConfigurationLocked(values, null, true);
12490 Binder.restoreCallingIdentity(origId);
12491 }
12492 }
12493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012494 public void updateConfiguration(Configuration values) {
12495 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12496 "updateConfiguration()");
12497
12498 synchronized(this) {
12499 if (values == null && mWindowManager != null) {
12500 // sentinel: fetch the current configuration from the window manager
12501 values = mWindowManager.computeNewConfiguration();
12502 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012503
12504 if (mWindowManager != null) {
12505 mProcessList.applyDisplaySize(mWindowManager);
12506 }
12507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012508 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012509 if (values != null) {
12510 Settings.System.clearConfiguration(values);
12511 }
12512 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012513 Binder.restoreCallingIdentity(origId);
12514 }
12515 }
12516
12517 /**
12518 * Do either or both things: (1) change the current configuration, and (2)
12519 * make sure the given activity is running with the (now) current
12520 * configuration. Returns true if the activity has been left running, or
12521 * false if <var>starting</var> is being destroyed to match the new
12522 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012523 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012524 */
12525 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012526 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012527 int changes = 0;
12528
12529 boolean kept = true;
12530
12531 if (values != null) {
12532 Configuration newConfig = new Configuration(mConfiguration);
12533 changes = newConfig.updateFrom(values);
12534 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012535 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012536 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012537 }
12538
Doug Zongker2bec3d42009-12-04 12:52:44 -080012539 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012540
12541 if (values.locale != null) {
12542 saveLocaleLocked(values.locale,
12543 !values.locale.equals(mConfiguration.locale),
12544 values.userSetLocale);
12545 }
12546
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012547 mConfigurationSeq++;
12548 if (mConfigurationSeq <= 0) {
12549 mConfigurationSeq = 1;
12550 }
12551 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012552 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012553 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012554
12555 AttributeCache ac = AttributeCache.instance();
12556 if (ac != null) {
12557 ac.updateConfiguration(mConfiguration);
12558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012559
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012560 // Make sure all resources in our process are updated
12561 // right now, so that anyone who is going to retrieve
12562 // resource values after we return will be sure to get
12563 // the new ones. This is especially important during
12564 // boot, where the first config change needs to guarantee
12565 // all resources have that config before following boot
12566 // code is executed.
12567 mSystemThread.applyConfigurationToResources(newConfig);
12568
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012569 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012570 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12571 msg.obj = new Configuration(mConfiguration);
12572 mHandler.sendMessage(msg);
12573 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012574
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012575 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12576 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012577 try {
12578 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012579 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012580 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012581 app.thread.scheduleConfigurationChanged(mConfiguration);
12582 }
12583 } catch (Exception e) {
12584 }
12585 }
12586 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012587 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12588 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012589 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12590 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012591 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12592 broadcastIntentLocked(null, null,
12593 new Intent(Intent.ACTION_LOCALE_CHANGED),
12594 null, null, 0, null, null,
12595 null, false, false, MY_PID, Process.SYSTEM_UID);
12596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012597 }
12598 }
12599
12600 if (changes != 0 && starting == null) {
12601 // If the configuration changed, and the caller is not already
12602 // in the process of starting an activity, then find the top
12603 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012604 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012605 }
12606
12607 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012608 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012609 // And we need to make sure at this point that all other activities
12610 // are made visible with the correct configuration.
12611 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012612 }
12613
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012614 if (values != null && mWindowManager != null) {
12615 mWindowManager.setNewConfiguration(mConfiguration);
12616 }
12617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012618 return kept;
12619 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012620
12621 /**
12622 * Save the locale. You must be inside a synchronized (this) block.
12623 */
12624 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12625 if(isDiff) {
12626 SystemProperties.set("user.language", l.getLanguage());
12627 SystemProperties.set("user.region", l.getCountry());
12628 }
12629
12630 if(isPersist) {
12631 SystemProperties.set("persist.sys.language", l.getLanguage());
12632 SystemProperties.set("persist.sys.country", l.getCountry());
12633 SystemProperties.set("persist.sys.localevar", l.getVariant());
12634 }
12635 }
12636
12637 // =========================================================
12638 // LIFETIME MANAGEMENT
12639 // =========================================================
12640
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012641 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12642 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012643 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012644 // This adjustment has already been computed. If we are calling
12645 // from the top, we may have already computed our adjustment with
12646 // an earlier hidden adjustment that isn't really for us... if
12647 // so, use the new hidden adjustment.
12648 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012649 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012650 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012651 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012652 }
12653
12654 if (app.thread == null) {
12655 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012656 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012657 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012658 }
12659
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012660 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12661 app.adjSource = null;
12662 app.adjTarget = null;
12663 app.empty = false;
12664 app.hidden = false;
12665
12666 final int activitiesSize = app.activities.size();
12667
Dianne Hackborn7d608422011-08-07 16:24:18 -070012668 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012669 // The max adjustment doesn't allow this app to be anything
12670 // below foreground, so it is not worth doing work for it.
12671 app.adjType = "fixed";
12672 app.adjSeq = mAdjSeq;
12673 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012674 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012675 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012676 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012677 // System process can do UI, and when they do we want to have
12678 // them trim their memory after the user leaves the UI. To
12679 // facilitate this, here we need to determine whether or not it
12680 // is currently showing UI.
12681 app.systemNoUi = true;
12682 if (app == TOP_APP) {
12683 app.systemNoUi = false;
12684 } else if (activitiesSize > 0) {
12685 for (int j = 0; j < activitiesSize; j++) {
12686 final ActivityRecord r = app.activities.get(j);
12687 if (r.visible) {
12688 app.systemNoUi = false;
12689 break;
12690 }
12691 }
12692 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012693 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012694 }
12695
12696 final boolean hadForegroundActivities = app.foregroundActivities;
12697
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012698 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012699 app.keeping = false;
12700 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012701
The Android Open Source Project4df24232009-03-05 14:34:35 -080012702 // Determine the importance of the process, starting with most
12703 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012704 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012705 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012706 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012707 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012708 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012709 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012710 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012711 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012712 } else if (app.instrumentationClass != null) {
12713 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012714 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012715 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012716 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012717 } else if (app.curReceiver != null ||
12718 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12719 // An app that is currently receiving a broadcast also
12720 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012721 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012722 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012723 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012724 } else if (app.executingServices.size() > 0) {
12725 // An app that is currently executing a service callback also
12726 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012727 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012728 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012729 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012730 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012731 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012732 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012733 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012734 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012735 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012736 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012737 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012738 // A very not-needed process. If this is lower in the lru list,
12739 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012740 adj = hiddenAdj;
12741 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012742 app.hidden = true;
12743 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012744 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012745 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012746
12747 // Examine all activities if not already foreground.
12748 if (!app.foregroundActivities && activitiesSize > 0) {
12749 for (int j = 0; j < activitiesSize; j++) {
12750 final ActivityRecord r = app.activities.get(j);
12751 if (r.visible) {
12752 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012753 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12754 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012755 app.adjType = "visible";
12756 }
12757 schedGroup = Process.THREAD_GROUP_DEFAULT;
12758 app.hidden = false;
12759 app.foregroundActivities = true;
12760 break;
12761 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12762 || r.state == ActivityState.STOPPING) {
12763 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012764 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12765 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012766 app.adjType = "stopping";
12767 }
12768 app.foregroundActivities = true;
12769 }
12770 }
12771 }
12772
Dianne Hackborn7d608422011-08-07 16:24:18 -070012773 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012774 if (app.foregroundServices) {
12775 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012776 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012777 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012778 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012779 } else if (app.forcingToForeground != null) {
12780 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012781 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012782 app.adjType = "force-foreground";
12783 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012784 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012785 }
12786 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012787
Dianne Hackborn7d608422011-08-07 16:24:18 -070012788 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012789 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012790 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012791 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12792 app.adjType = "heavy";
12793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012794
Dianne Hackborn7d608422011-08-07 16:24:18 -070012795 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012796 // This process is hosting what we currently consider to be the
12797 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012798 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012799 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12800 app.adjType = "home";
12801 }
12802
Joe Onorato8a9b2202010-02-26 18:56:32 -080012803 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012804
The Android Open Source Project4df24232009-03-05 14:34:35 -080012805 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012806 // there are applications dependent on our services or providers, but
12807 // this gives us a baseline and makes sure we don't get into an
12808 // infinite recursion.
12809 app.adjSeq = mAdjSeq;
12810 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012811
Christopher Tate6fa95972009-06-05 18:43:55 -070012812 if (mBackupTarget != null && app == mBackupTarget.app) {
12813 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012814 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012815 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012816 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012817 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012818 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012819 }
12820 }
12821
Dianne Hackborn7d608422011-08-07 16:24:18 -070012822 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012823 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012824 final long now = SystemClock.uptimeMillis();
12825 // This process is more important if the top activity is
12826 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012827 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012828 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012829 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012830 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012831 if (app.hasShownUi) {
12832 // If this process has shown some UI, let it immediately
12833 // go to the LRU list because it may be pretty heavy with
12834 // UI stuff. We'll tag it with a label just to help
12835 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012836 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012837 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012838 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012839 } else {
12840 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12841 // This service has seen some activity within
12842 // recent memory, so we will keep its process ahead
12843 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012844 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
12845 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012846 app.adjType = "started-services";
12847 app.hidden = false;
12848 }
12849 }
12850 // If we have let the service slide into the background
12851 // state, still have some text describing what it is doing
12852 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012853 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012854 app.adjType = "started-bg-services";
12855 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012856 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012857 // Don't kill this process because it is doing work; it
12858 // has said it is doing work.
12859 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012860 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012861 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012862 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012863 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012864 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012865 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012866 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012867 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012868 // XXX should compute this based on the max of
12869 // all connected clients.
12870 ConnectionRecord cr = clist.get(i);
12871 if (cr.binding.client == app) {
12872 // Binding to ourself is not interesting.
12873 continue;
12874 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012875 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012876 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012877 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012878 int myHiddenAdj = hiddenAdj;
12879 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012880 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012881 myHiddenAdj = client.hiddenAdj;
12882 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012883 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012884 }
12885 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012886 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012887 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012888 String adjType = null;
12889 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12890 // Not doing bind OOM management, so treat
12891 // this guy more like a started service.
12892 if (app.hasShownUi) {
12893 // If this process has shown some UI, let it immediately
12894 // go to the LRU list because it may be pretty heavy with
12895 // UI stuff. We'll tag it with a label just to help
12896 // debug and understand what is going on.
12897 if (adj > clientAdj) {
12898 adjType = "bound-bg-ui-services";
12899 }
12900 clientAdj = adj;
12901 } else {
12902 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
12903 // This service has not seen activity within
12904 // recent memory, so allow it to drop to the
12905 // LRU list if there is no other reason to keep
12906 // it around. We'll also tag it with a label just
12907 // to help debug and undertand what is going on.
12908 if (adj > clientAdj) {
12909 adjType = "bound-bg-services";
12910 }
12911 clientAdj = adj;
12912 }
12913 }
12914 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012915 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012916 // If this process has recently shown UI, and
12917 // the process that is binding to it is less
12918 // important than being visible, then we don't
12919 // care about the binding as much as we care
12920 // about letting this process get into the LRU
12921 // list to be killed and restarted if needed for
12922 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012923 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012924 adjType = "bound-bg-ui-services";
12925 } else {
12926 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12927 |Context.BIND_IMPORTANT)) != 0) {
12928 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012929 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012930 adj = clientAdj;
12931 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012932 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012933 }
12934 if (!client.hidden) {
12935 app.hidden = false;
12936 }
12937 if (client.keeping) {
12938 app.keeping = true;
12939 }
12940 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012941 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012942 }
12943 if (adjType != null) {
12944 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012945 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12946 .REASON_SERVICE_IN_USE;
12947 app.adjSource = cr.binding.client;
12948 app.adjTarget = s.name;
12949 }
12950 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12951 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12952 schedGroup = Process.THREAD_GROUP_DEFAULT;
12953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012954 }
12955 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012956 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12957 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012958 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012959 (a.visible || a.state == ActivityState.RESUMED
12960 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012961 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012962 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12963 schedGroup = Process.THREAD_GROUP_DEFAULT;
12964 }
12965 app.hidden = false;
12966 app.adjType = "service";
12967 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12968 .REASON_SERVICE_IN_USE;
12969 app.adjSource = a;
12970 app.adjTarget = s.name;
12971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012973 }
12974 }
12975 }
12976 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012977
Dianne Hackborn287952c2010-09-22 22:34:31 -070012978 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012979 // would like to avoid killing it unless it would prevent the current
12980 // application from running. By default we put the process in
12981 // with the rest of the background processes; as we scan through
12982 // its services we may bump it up from there.
12983 if (adj > hiddenAdj) {
12984 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012985 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012986 app.adjType = "bg-services";
12987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012988 }
12989
Dianne Hackborn7d608422011-08-07 16:24:18 -070012990 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012991 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012992 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012993 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012994 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012995 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012996 if (cpr.clients.size() != 0) {
12997 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012998 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013000 if (client == app) {
13001 // Being our own client is not interesting.
13002 continue;
13003 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013004 int myHiddenAdj = hiddenAdj;
13005 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013006 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013007 myHiddenAdj = client.hiddenAdj;
13008 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013009 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013010 }
13011 }
13012 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013013 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013014 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013015 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013016 app.adjType = "bg-ui-provider";
13017 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013018 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13019 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013020 app.adjType = "provider";
13021 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013022 if (!client.hidden) {
13023 app.hidden = false;
13024 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013025 if (client.keeping) {
13026 app.keeping = true;
13027 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013028 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13029 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013030 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013031 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013032 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013033 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13034 schedGroup = Process.THREAD_GROUP_DEFAULT;
13035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013036 }
13037 }
13038 // If the provider has external (non-framework) process
13039 // dependencies, ensure that its adjustment is at least
13040 // FOREGROUND_APP_ADJ.
13041 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013042 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13043 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013044 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013045 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013046 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013047 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013048 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013049 }
13050 }
13051 }
13052 }
13053
13054 app.curRawAdj = adj;
13055
Joe Onorato8a9b2202010-02-26 18:56:32 -080013056 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013057 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13058 if (adj > app.maxAdj) {
13059 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013060 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013061 schedGroup = Process.THREAD_GROUP_DEFAULT;
13062 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013063 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013064 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013065 app.keeping = true;
13066 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013067
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013068 if (app.hasAboveClient) {
13069 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13070 // then we need to drop its adjustment to be lower than the service's
13071 // in order to honor the request. We want to drop it by one adjustment
13072 // level... but there is special meaning applied to various levels so
13073 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013074 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013075 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013076 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13077 adj = ProcessList.VISIBLE_APP_ADJ;
13078 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13079 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13080 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13081 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13082 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013083 adj++;
13084 }
13085 }
13086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013087 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013088 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013089
13090 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013091 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13092 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013093 }
13094
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013095 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013096 }
13097
13098 /**
13099 * Ask a given process to GC right now.
13100 */
13101 final void performAppGcLocked(ProcessRecord app) {
13102 try {
13103 app.lastRequestedGc = SystemClock.uptimeMillis();
13104 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013105 if (app.reportLowMemory) {
13106 app.reportLowMemory = false;
13107 app.thread.scheduleLowMemory();
13108 } else {
13109 app.thread.processInBackground();
13110 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013111 }
13112 } catch (Exception e) {
13113 // whatever.
13114 }
13115 }
13116
13117 /**
13118 * Returns true if things are idle enough to perform GCs.
13119 */
Josh Bartel7f208742010-02-25 11:01:44 -060013120 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013121 return mParallelBroadcasts.size() == 0
13122 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013123 && (mSleeping || (mMainStack.mResumedActivity != null &&
13124 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013125 }
13126
13127 /**
13128 * Perform GCs on all processes that are waiting for it, but only
13129 * if things are idle.
13130 */
13131 final void performAppGcsLocked() {
13132 final int N = mProcessesToGc.size();
13133 if (N <= 0) {
13134 return;
13135 }
Josh Bartel7f208742010-02-25 11:01:44 -060013136 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013137 while (mProcessesToGc.size() > 0) {
13138 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013139 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013140 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13141 <= SystemClock.uptimeMillis()) {
13142 // To avoid spamming the system, we will GC processes one
13143 // at a time, waiting a few seconds between each.
13144 performAppGcLocked(proc);
13145 scheduleAppGcsLocked();
13146 return;
13147 } else {
13148 // It hasn't been long enough since we last GCed this
13149 // process... put it in the list to wait for its time.
13150 addProcessToGcListLocked(proc);
13151 break;
13152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013153 }
13154 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013155
13156 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013157 }
13158 }
13159
13160 /**
13161 * If all looks good, perform GCs on all processes waiting for them.
13162 */
13163 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013164 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013165 performAppGcsLocked();
13166 return;
13167 }
13168 // Still not idle, wait some more.
13169 scheduleAppGcsLocked();
13170 }
13171
13172 /**
13173 * Schedule the execution of all pending app GCs.
13174 */
13175 final void scheduleAppGcsLocked() {
13176 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013177
13178 if (mProcessesToGc.size() > 0) {
13179 // Schedule a GC for the time to the next process.
13180 ProcessRecord proc = mProcessesToGc.get(0);
13181 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13182
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013183 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013184 long now = SystemClock.uptimeMillis();
13185 if (when < (now+GC_TIMEOUT)) {
13186 when = now + GC_TIMEOUT;
13187 }
13188 mHandler.sendMessageAtTime(msg, when);
13189 }
13190 }
13191
13192 /**
13193 * Add a process to the array of processes waiting to be GCed. Keeps the
13194 * list in sorted order by the last GC time. The process can't already be
13195 * on the list.
13196 */
13197 final void addProcessToGcListLocked(ProcessRecord proc) {
13198 boolean added = false;
13199 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13200 if (mProcessesToGc.get(i).lastRequestedGc <
13201 proc.lastRequestedGc) {
13202 added = true;
13203 mProcessesToGc.add(i+1, proc);
13204 break;
13205 }
13206 }
13207 if (!added) {
13208 mProcessesToGc.add(0, proc);
13209 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013210 }
13211
13212 /**
13213 * Set up to ask a process to GC itself. This will either do it
13214 * immediately, or put it on the list of processes to gc the next
13215 * time things are idle.
13216 */
13217 final void scheduleAppGcLocked(ProcessRecord app) {
13218 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013219 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013220 return;
13221 }
13222 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013223 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013224 scheduleAppGcsLocked();
13225 }
13226 }
13227
Dianne Hackborn287952c2010-09-22 22:34:31 -070013228 final void checkExcessivePowerUsageLocked(boolean doKills) {
13229 updateCpuStatsNow();
13230
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013231 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013232 boolean doWakeKills = doKills;
13233 boolean doCpuKills = doKills;
13234 if (mLastPowerCheckRealtime == 0) {
13235 doWakeKills = false;
13236 }
13237 if (mLastPowerCheckUptime == 0) {
13238 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013239 }
13240 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013241 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013242 }
13243 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013244 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13245 final long curUptime = SystemClock.uptimeMillis();
13246 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13247 mLastPowerCheckRealtime = curRealtime;
13248 mLastPowerCheckUptime = curUptime;
13249 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13250 doWakeKills = false;
13251 }
13252 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13253 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013254 }
13255 int i = mLruProcesses.size();
13256 while (i > 0) {
13257 i--;
13258 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013259 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013260 long wtime;
13261 synchronized (stats) {
13262 wtime = stats.getProcessWakeTime(app.info.uid,
13263 app.pid, curRealtime);
13264 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013265 long wtimeUsed = wtime - app.lastWakeTime;
13266 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13267 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013268 StringBuilder sb = new StringBuilder(128);
13269 sb.append("Wake for ");
13270 app.toShortString(sb);
13271 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013272 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013273 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013274 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013275 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013276 sb.append((wtimeUsed*100)/realtimeSince);
13277 sb.append("%)");
13278 Slog.i(TAG, sb.toString());
13279 sb.setLength(0);
13280 sb.append("CPU for ");
13281 app.toShortString(sb);
13282 sb.append(": over ");
13283 TimeUtils.formatDuration(uptimeSince, sb);
13284 sb.append(" used ");
13285 TimeUtils.formatDuration(cputimeUsed, sb);
13286 sb.append(" (");
13287 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013288 sb.append("%)");
13289 Slog.i(TAG, sb.toString());
13290 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013291 // If a process has held a wake lock for more
13292 // than 50% of the time during this period,
13293 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013294 if (doWakeKills && realtimeSince > 0
13295 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13296 synchronized (stats) {
13297 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13298 realtimeSince, wtimeUsed);
13299 }
13300 Slog.w(TAG, "Excessive wake lock in " + app.processName
13301 + " (pid " + app.pid + "): held " + wtimeUsed
13302 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013303 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13304 app.processName, app.setAdj, "excessive wake lock");
13305 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013306 } else if (doCpuKills && uptimeSince > 0
13307 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13308 synchronized (stats) {
13309 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13310 uptimeSince, cputimeUsed);
13311 }
13312 Slog.w(TAG, "Excessive CPU in " + app.processName
13313 + " (pid " + app.pid + "): used " + cputimeUsed
13314 + " during " + uptimeSince);
13315 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13316 app.processName, app.setAdj, "excessive cpu");
13317 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013318 } else {
13319 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013320 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013321 }
13322 }
13323 }
13324 }
13325
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013326 private final void updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013327 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013328 app.hiddenAdj = hiddenAdj;
13329
13330 if (app.thread == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013331 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013332 }
13333
Dianne Hackborn287952c2010-09-22 22:34:31 -070013334 final boolean wasKeeping = app.keeping;
13335
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013336 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013337
Jeff Brown10e89712011-07-08 18:52:57 -070013338 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013339 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13340 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013341 // If this app is transitioning from foreground to
13342 // non-foreground, have it do a gc.
13343 scheduleAppGcLocked(app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013344 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13345 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013346 // Likewise do a gc when an app is moving in to the
13347 // background (such as a service stopping).
13348 scheduleAppGcLocked(app);
13349 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013350
Jeff Brown10e89712011-07-08 18:52:57 -070013351 if (wasKeeping && !app.keeping) {
13352 // This app is no longer something we want to keep. Note
13353 // its current wake lock time to later know to kill it if
13354 // it is not behaving well.
13355 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13356 synchronized (stats) {
13357 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13358 app.pid, SystemClock.elapsedRealtime());
13359 }
13360 app.lastCpuTime = app.curCpuTime;
13361 }
13362
13363 app.setRawAdj = app.curRawAdj;
13364 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013365 if (app.curAdj != app.setAdj) {
13366 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013367 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13368 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013369 " oom adj to " + app.curAdj + " because " + app.adjType);
13370 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013371 } else {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013372 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013373 }
13374 }
13375 if (app.setSchedGroup != app.curSchedGroup) {
13376 app.setSchedGroup = app.curSchedGroup;
13377 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13378 "Setting process group of " + app.processName
13379 + " to " + app.curSchedGroup);
13380 if (app.waitingToKill != null &&
13381 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13382 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13383 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13384 app.processName, app.setAdj, app.waitingToKill);
13385 Process.killProcessQuiet(app.pid);
13386 } else {
13387 if (true) {
13388 long oldId = Binder.clearCallingIdentity();
13389 try {
13390 Process.setProcessGroup(app.pid, app.curSchedGroup);
13391 } catch (Exception e) {
13392 Slog.w(TAG, "Failed setting process group of " + app.pid
13393 + " to " + app.curSchedGroup);
13394 e.printStackTrace();
13395 } finally {
13396 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013397 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013398 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013399 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013400 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013401 app.thread.setSchedulingGroup(app.curSchedGroup);
13402 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013403 }
13404 }
13405 }
13406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013407 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013408 }
13409
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013410 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013411 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013412 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013413 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013414 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013415 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013416 }
13417 }
13418 return resumedActivity;
13419 }
13420
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013421 private final void updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013422 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013423 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13424 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013425 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13426 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013427
13428 mAdjSeq++;
13429
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013430 updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013431 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13432 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013433 if (nowHidden != wasHidden) {
13434 // Changed to/from hidden state, so apps after it in the LRU
13435 // list may also be changed.
13436 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013438 }
13439
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013440 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013441 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013442 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13443
13444 if (false) {
13445 RuntimeException e = new RuntimeException();
13446 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013447 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013448 }
13449
13450 mAdjSeq++;
13451
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013452 // Let's determine how many processes we have running vs.
13453 // how many slots we have for background processes; we may want
13454 // to put multiple processes in a slot of there are enough of
13455 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013456 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013457 int factor = (mLruProcesses.size()-4)/numSlots;
13458 if (factor < 1) factor = 1;
13459 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013460 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013461
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013462 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013463 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013464 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013465 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013466 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013467 while (i > 0) {
13468 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013469 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013470 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013471 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013472 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013473 && app.curAdj == curHiddenAdj) {
13474 step++;
13475 if (step >= factor) {
13476 step = 0;
13477 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013478 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013479 }
13480 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013481 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013482 numHidden++;
13483 if (numHidden > mProcessLimit) {
13484 Slog.i(TAG, "No longer want " + app.processName
13485 + " (pid " + app.pid + "): hidden #" + numHidden);
13486 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13487 app.processName, app.setAdj, "too many background");
13488 app.killedBackground = true;
13489 Process.killProcessQuiet(app.pid);
13490 } else {
13491 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013492 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013493 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013494 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013496 }
13497 }
13498
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013499 // Now determine the memory trimming level of background processes.
13500 // Unfortunately we need to start at the back of the list to do this
13501 // properly. We only do this if the number of background apps we
13502 // are managing to keep around is less than half the maximum we desire;
13503 // if we are keeping a good number around, we'll let them use whatever
13504 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013505 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013506 final int N = mLruProcesses.size();
13507 factor = numBg/3;
13508 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013509 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013510 for (i=0; i<N; i++) {
13511 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013512 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013513 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13514 try {
13515 app.thread.scheduleTrimMemory(curLevel);
13516 } catch (RemoteException e) {
13517 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013518 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013519 // For these apps we will also finish their activities
13520 // to help them free memory.
13521 mMainStack.destroyActivitiesLocked(app, false);
13522 }
13523 }
13524 app.trimMemoryLevel = curLevel;
13525 step++;
13526 if (step >= factor) {
13527 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013528 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13529 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013530 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013531 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13532 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013533 break;
13534 }
13535 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013536 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013537 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013538 && app.thread != null) {
13539 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013540 app.thread.scheduleTrimMemory(
13541 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013542 } catch (RemoteException e) {
13543 }
13544 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013545 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013546 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013547 && app.pendingUiClean) {
13548 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13549 && app.thread != null) {
13550 try {
13551 app.thread.scheduleTrimMemory(
13552 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13553 } catch (RemoteException e) {
13554 }
13555 }
13556 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13557 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013558 } else {
13559 app.trimMemoryLevel = 0;
13560 }
13561 }
13562 } else {
13563 final int N = mLruProcesses.size();
13564 for (i=0; i<N; i++) {
13565 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013566 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013567 && app.pendingUiClean) {
13568 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13569 && app.thread != null) {
13570 try {
13571 app.thread.scheduleTrimMemory(
13572 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13573 } catch (RemoteException e) {
13574 }
13575 }
13576 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13577 app.pendingUiClean = false;
13578 } else {
13579 app.trimMemoryLevel = 0;
13580 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013581 }
13582 }
13583
13584 if (mAlwaysFinishActivities) {
13585 mMainStack.destroyActivitiesLocked(null, false);
13586 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013587 }
13588
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013589 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013590 synchronized (this) {
13591 int i;
13592
13593 // First remove any unused application processes whose package
13594 // has been removed.
13595 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13596 final ProcessRecord app = mRemovedProcesses.get(i);
13597 if (app.activities.size() == 0
13598 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013599 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013600 TAG, "Exiting empty application process "
13601 + app.processName + " ("
13602 + (app.thread != null ? app.thread.asBinder() : null)
13603 + ")\n");
13604 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013605 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13606 app.processName, app.setAdj, "empty");
13607 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013608 } else {
13609 try {
13610 app.thread.scheduleExit();
13611 } catch (Exception e) {
13612 // Ignore exceptions.
13613 }
13614 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013615 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013616 mRemovedProcesses.remove(i);
13617
13618 if (app.persistent) {
13619 if (app.persistent) {
13620 addAppLocked(app.info);
13621 }
13622 }
13623 }
13624 }
13625
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013626 // Now update the oom adj for all processes.
13627 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013628 }
13629 }
13630
13631 /** This method sends the specified signal to each of the persistent apps */
13632 public void signalPersistentProcesses(int sig) throws RemoteException {
13633 if (sig != Process.SIGNAL_USR1) {
13634 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13635 }
13636
13637 synchronized (this) {
13638 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13639 != PackageManager.PERMISSION_GRANTED) {
13640 throw new SecurityException("Requires permission "
13641 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13642 }
13643
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013644 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13645 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013646 if (r.thread != null && r.persistent) {
13647 Process.sendSignal(r.pid, sig);
13648 }
13649 }
13650 }
13651 }
13652
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013653 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13654 if (proc == null || proc == mProfileProc) {
13655 proc = mProfileProc;
13656 path = mProfileFile;
13657 profileType = mProfileType;
13658 clearProfilerLocked();
13659 }
13660 if (proc == null) {
13661 return;
13662 }
13663 try {
13664 proc.thread.profilerControl(false, path, null, profileType);
13665 } catch (RemoteException e) {
13666 throw new IllegalStateException("Process disappeared");
13667 }
13668 }
13669
13670 private void clearProfilerLocked() {
13671 if (mProfileFd != null) {
13672 try {
13673 mProfileFd.close();
13674 } catch (IOException e) {
13675 }
13676 }
13677 mProfileApp = null;
13678 mProfileProc = null;
13679 mProfileFile = null;
13680 mProfileType = 0;
13681 mAutoStopProfiler = false;
13682 }
13683
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013684 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013685 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013686
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013687 try {
13688 synchronized (this) {
13689 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13690 // its own permission.
13691 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13692 != PackageManager.PERMISSION_GRANTED) {
13693 throw new SecurityException("Requires permission "
13694 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013695 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013696
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013697 if (start && fd == null) {
13698 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013699 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013700
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013701 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013702 if (process != null) {
13703 try {
13704 int pid = Integer.parseInt(process);
13705 synchronized (mPidsSelfLocked) {
13706 proc = mPidsSelfLocked.get(pid);
13707 }
13708 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013709 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013710
13711 if (proc == null) {
13712 HashMap<String, SparseArray<ProcessRecord>> all
13713 = mProcessNames.getMap();
13714 SparseArray<ProcessRecord> procs = all.get(process);
13715 if (procs != null && procs.size() > 0) {
13716 proc = procs.valueAt(0);
13717 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013718 }
13719 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013720
13721 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013722 throw new IllegalArgumentException("Unknown process: " + process);
13723 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013724
13725 if (start) {
13726 stopProfilerLocked(null, null, 0);
13727 setProfileApp(proc.info, proc.processName, path, fd, false);
13728 mProfileProc = proc;
13729 mProfileType = profileType;
13730 try {
13731 fd = fd.dup();
13732 } catch (IOException e) {
13733 fd = null;
13734 }
13735 proc.thread.profilerControl(start, path, fd, profileType);
13736 fd = null;
13737 mProfileFd = null;
13738 } else {
13739 stopProfilerLocked(proc, path, profileType);
13740 if (fd != null) {
13741 try {
13742 fd.close();
13743 } catch (IOException e) {
13744 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013745 }
13746 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013747
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013748 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013749 }
13750 } catch (RemoteException e) {
13751 throw new IllegalStateException("Process disappeared");
13752 } finally {
13753 if (fd != null) {
13754 try {
13755 fd.close();
13756 } catch (IOException e) {
13757 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013758 }
13759 }
13760 }
Andy McFadden824c5102010-07-09 16:26:57 -070013761
13762 public boolean dumpHeap(String process, boolean managed,
13763 String path, ParcelFileDescriptor fd) throws RemoteException {
13764
13765 try {
13766 synchronized (this) {
13767 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13768 // its own permission (same as profileControl).
13769 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13770 != PackageManager.PERMISSION_GRANTED) {
13771 throw new SecurityException("Requires permission "
13772 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13773 }
13774
13775 if (fd == null) {
13776 throw new IllegalArgumentException("null fd");
13777 }
13778
13779 ProcessRecord proc = null;
13780 try {
13781 int pid = Integer.parseInt(process);
13782 synchronized (mPidsSelfLocked) {
13783 proc = mPidsSelfLocked.get(pid);
13784 }
13785 } catch (NumberFormatException e) {
13786 }
13787
13788 if (proc == null) {
13789 HashMap<String, SparseArray<ProcessRecord>> all
13790 = mProcessNames.getMap();
13791 SparseArray<ProcessRecord> procs = all.get(process);
13792 if (procs != null && procs.size() > 0) {
13793 proc = procs.valueAt(0);
13794 }
13795 }
13796
13797 if (proc == null || proc.thread == null) {
13798 throw new IllegalArgumentException("Unknown process: " + process);
13799 }
13800
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013801 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13802 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013803 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13804 throw new SecurityException("Process not debuggable: " + proc);
13805 }
13806 }
13807
13808 proc.thread.dumpHeap(managed, path, fd);
13809 fd = null;
13810 return true;
13811 }
13812 } catch (RemoteException e) {
13813 throw new IllegalStateException("Process disappeared");
13814 } finally {
13815 if (fd != null) {
13816 try {
13817 fd.close();
13818 } catch (IOException e) {
13819 }
13820 }
13821 }
13822 }
13823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013824 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13825 public void monitor() {
13826 synchronized (this) { }
13827 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013828
13829 public void onCoreSettingsChange(Bundle settings) {
13830 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13831 ProcessRecord processRecord = mLruProcesses.get(i);
13832 try {
13833 if (processRecord.thread != null) {
13834 processRecord.thread.setCoreSettings(settings);
13835 }
13836 } catch (RemoteException re) {
13837 /* ignore */
13838 }
13839 }
13840 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013841
13842 // Multi-user methods
13843
13844 public boolean switchUser(int userid) {
13845 // TODO
13846 return true;
13847 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013848}