blob: bb5e989a534a8c76f8d5cf342125f8ffa25f5f43 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Dianne Hackborn860755f2010-06-03 18:47:52 -070019import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070021import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070022import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080023import com.android.server.IntentResolver;
24import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.SystemServer;
26import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070027import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080028import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029
Dianne Hackborndd71fc82009-12-16 19:24:32 -080030import dalvik.system.Zygote;
31
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080032import android.app.Activity;
33import android.app.ActivityManager;
34import android.app.ActivityManagerNative;
35import android.app.ActivityThread;
36import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070037import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020038import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070040import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.app.IActivityWatcher;
42import android.app.IApplicationThread;
43import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070044import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070045import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IServiceConnection;
47import android.app.IThumbnailReceiver;
48import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070049import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070050import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070052import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080053import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020054import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080055import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070056import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.content.ComponentName;
58import android.content.ContentResolver;
59import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020060import android.content.DialogInterface;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.content.Intent;
62import android.content.IntentFilter;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070063import android.content.IIntentReceiver;
64import android.content.IIntentSender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070065import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.content.pm.ActivityInfo;
67import android.content.pm.ApplicationInfo;
68import android.content.pm.ConfigurationInfo;
69import android.content.pm.IPackageDataObserver;
70import android.content.pm.IPackageManager;
71import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080072import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.content.pm.PackageManager;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070074import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.content.pm.ProviderInfo;
76import android.content.pm.ResolveInfo;
77import android.content.pm.ServiceInfo;
Dianne Hackborn860755f2010-06-03 18:47:52 -070078import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040079import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.content.res.Configuration;
81import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070082import android.net.Proxy;
83import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.net.Uri;
85import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080086import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080087import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070088import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080089import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080091import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import android.os.FileUtils;
93import android.os.Handler;
94import android.os.IBinder;
95import android.os.IPermissionController;
96import android.os.Looper;
97import android.os.Message;
98import android.os.Parcel;
99import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700101import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import android.os.RemoteException;
103import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700104import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105import android.os.SystemClock;
106import android.os.SystemProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.provider.Settings;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.util.EventLog;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800109import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800110import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.util.PrintWriterPrinter;
112import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700113import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114import android.view.Gravity;
115import android.view.LayoutInflater;
116import android.view.View;
117import android.view.WindowManager;
118import android.view.WindowManagerPolicy;
119
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700120import java.io.BufferedInputStream;
121import java.io.BufferedOutputStream;
122import java.io.DataInputStream;
123import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124import java.io.File;
125import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700126import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200129import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800130import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131import java.io.PrintWriter;
132import java.lang.IllegalStateException;
133import java.lang.ref.WeakReference;
134import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700135import java.util.Collections;
136import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.util.HashMap;
138import java.util.HashSet;
139import java.util.Iterator;
140import java.util.List;
141import java.util.Locale;
142import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700143import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700144import java.util.concurrent.atomic.AtomicBoolean;
145import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700147public final class ActivityManagerService extends ActivityManagerNative
148 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149 static final String TAG = "ActivityManager";
150 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400151 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final boolean DEBUG_SWITCH = localLOGV || false;
153 static final boolean DEBUG_TASKS = localLOGV || false;
154 static final boolean DEBUG_PAUSE = localLOGV || false;
155 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
156 static final boolean DEBUG_TRANSITION = localLOGV || false;
157 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700158 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700160 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 static final boolean DEBUG_VISBILITY = localLOGV || false;
162 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700163 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800164 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700166 static final boolean DEBUG_RESULTS = localLOGV || false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700167 static final boolean DEBUG_BACKUP = localLOGV || true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700168 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final boolean DEBUG_POWER = localLOGV || false;
170 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean VALIDATE_TOKENS = false;
172 static final boolean SHOW_ACTIVITY_START_TIME = true;
173
174 // Control over CPU and battery monitoring.
175 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
176 static final boolean MONITOR_CPU_USAGE = true;
177 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
178 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
179 static final boolean MONITOR_THREAD_CPU_USAGE = false;
180
Dianne Hackborn1655be42009-05-08 14:29:01 -0700181 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700182 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700183
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800184 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800186 // Maximum number of recent tasks that we can remember.
187 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700188
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700189 // Amount of time after a call to stopAppSwitches() during which we will
190 // prevent further untrusted switches from happening.
191 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192
193 // How long we wait for a launched process to attach to the activity manager
194 // before we decide it's never going to come up for real.
195 static final int PROC_START_TIMEOUT = 10*1000;
196
Jeff Brown3f9dd282011-07-08 20:02:19 -0700197 // How long we wait for a launched process to attach to the activity manager
198 // before we decide it's never going to come up for real, when the process was
199 // started with a wrapper for instrumentation (such as Valgrind) because it
200 // could take much longer than usual.
201 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800203 // How long to wait after going idle before forcing apps to GC.
204 static final int GC_TIMEOUT = 5*1000;
205
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700206 // The minimum amount of time between successive GC requests for a process.
207 static final int GC_MIN_INTERVAL = 60*1000;
208
Dianne Hackborn287952c2010-09-22 22:34:31 -0700209 // The rate at which we check for apps using excessive power -- 15 mins.
210 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
211
212 // The minimum sample duration we will allow before deciding we have
213 // enough data on wake locks to start killing things.
214 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
215
216 // The minimum sample duration we will allow before deciding we have
217 // enough data on CPU usage to start killing things.
218 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800220 // How long we allow a receiver to run before giving up on it.
221 static final int BROADCAST_TIMEOUT = 10*1000;
222
223 // How long we wait for a service to finish executing.
224 static final int SERVICE_TIMEOUT = 20*1000;
225
226 // How long a service needs to be running until restarting its process
227 // is no longer considered to be a relaunch of the service.
228 static final int SERVICE_RESTART_DURATION = 5*1000;
229
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700230 // How long a service needs to be running until it will start back at
231 // SERVICE_RESTART_DURATION after being killed.
232 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
233
234 // Multiplying factor to increase restart duration time by, for each time
235 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
236 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
237
238 // The minimum amount of time between restarting services that we allow.
239 // That is, when multiple services are restarting, we won't allow each
240 // to restart less than this amount of time from the last one.
241 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
242
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800243 // Maximum amount of time for there to be no activity on a service before
244 // we consider it non-essential and allow its process to go on the
245 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700246 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247
248 // How long we wait until we timeout on key dispatching.
249 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 // How long we wait until we timeout on key dispatching during instrumentation.
252 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
253
Dan Egnor42471dd2010-01-07 17:25:22 -0800254 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255
256 static final String[] EMPTY_STRING_ARRAY = new String[0];
257
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700258 public ActivityStack mMainStack;
259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700261 * Description of a request to start a new activity, which has been held
262 * due to app switches being disabled.
263 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700264 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700265 ActivityRecord r;
266 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700267 Uri[] grantedUriPermissions;
268 int grantedMode;
269 boolean onlyIfNeeded;
270 }
271
272 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
273 = new ArrayList<PendingActivityLaunch>();
274
275 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 * List of all active broadcasts that are to be executed immediately
277 * (without waiting for another broadcast to finish). Currently this only
278 * contains broadcasts to registered receivers, to avoid spinning up
279 * a bunch of processes to execute IntentReceiver components.
280 */
281 final ArrayList<BroadcastRecord> mParallelBroadcasts
282 = new ArrayList<BroadcastRecord>();
283
284 /**
285 * List of all active broadcasts that are to be executed one at a time.
286 * The object at the top of the list is the currently activity broadcasts;
287 * those after it are waiting for the top to finish..
288 */
289 final ArrayList<BroadcastRecord> mOrderedBroadcasts
290 = new ArrayList<BroadcastRecord>();
291
292 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800293 * Historical data of past broadcasts, for debugging.
294 */
295 static final int MAX_BROADCAST_HISTORY = 100;
296 final BroadcastRecord[] mBroadcastHistory
297 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
298
299 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800300 * Set when we current have a BROADCAST_INTENT_MSG in flight.
301 */
302 boolean mBroadcastsScheduled = false;
303
304 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 * Activity we have told the window manager to have key focus.
306 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700307 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700308 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 * List of intents that were used to start the most recent tasks.
310 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
313 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700314 * Process management.
315 */
316 final ProcessList mProcessList = new ProcessList();
317
318 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 * All of the applications we currently have running organized by name.
320 * The keys are strings of the application package name (as
321 * returned by the package manager), and the keys are ApplicationRecord
322 * objects.
323 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325
326 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700327 * The currently running heavy-weight process, if any.
328 */
329 ProcessRecord mHeavyWeightProcess = null;
330
331 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 * The last time that various processes have crashed.
333 */
334 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
335
336 /**
337 * Set of applications that we consider to be bad, and will reject
338 * incoming broadcasts from (which the user has no control over).
339 * Processes are added to this set when they have crashed twice within
340 * a minimum amount of time; they are removed from it when they are
341 * later restarted (hopefully due to some user action). The value is the
342 * time it was added to the list.
343 */
344 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
345
346 /**
347 * All of the processes we currently have running organized by pid.
348 * The keys are the pid running the application.
349 *
350 * <p>NOTE: This object is protected by its own lock, NOT the global
351 * activity manager lock!
352 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700353 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800354
355 /**
356 * All of the processes that have been forced to be foreground. The key
357 * is the pid of the caller who requested it (we hold a death
358 * link on it).
359 */
360 abstract class ForegroundToken implements IBinder.DeathRecipient {
361 int pid;
362 IBinder token;
363 }
364 final SparseArray<ForegroundToken> mForegroundProcesses
365 = new SparseArray<ForegroundToken>();
366
367 /**
368 * List of records for processes that someone had tried to start before the
369 * system was ready. We don't start them at that point, but ensure they
370 * are started by the time booting is complete.
371 */
372 final ArrayList<ProcessRecord> mProcessesOnHold
373 = new ArrayList<ProcessRecord>();
374
375 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800376 * List of persistent applications that are in the process
377 * of being started.
378 */
379 final ArrayList<ProcessRecord> mPersistentStartingProcesses
380 = new ArrayList<ProcessRecord>();
381
382 /**
383 * Processes that are being forcibly torn down.
384 */
385 final ArrayList<ProcessRecord> mRemovedProcesses
386 = new ArrayList<ProcessRecord>();
387
388 /**
389 * List of running applications, sorted by recent usage.
390 * The first entry in the list is the least recently used.
391 * It contains ApplicationRecord objects. This list does NOT include
392 * any persistent application records (since we never want to exit them).
393 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800394 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800395 = new ArrayList<ProcessRecord>();
396
397 /**
398 * List of processes that should gc as soon as things are idle.
399 */
400 final ArrayList<ProcessRecord> mProcessesToGc
401 = new ArrayList<ProcessRecord>();
402
403 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800404 * This is the process holding what we currently consider to be
405 * the "home" activity.
406 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700407 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800408
409 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400410 * Packages that the user has asked to have run in screen size
411 * compatibility mode instead of filling the screen.
412 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700413 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400414
415 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 * Set of PendingResultRecord objects that are currently active.
417 */
418 final HashSet mPendingResultRecords = new HashSet();
419
420 /**
421 * Set of IntentSenderRecord objects that are currently active.
422 */
423 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
424 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
425
426 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800427 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700428 * already logged DropBox entries for. Guarded by itself. If
429 * something (rogue user app) forces this over
430 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
431 */
432 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
433 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
434
435 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700436 * Strict Mode background batched logging state.
437 *
438 * The string buffer is guarded by itself, and its lock is also
439 * used to determine if another batched write is already
440 * in-flight.
441 */
442 private final StringBuilder mStrictModeBuffer = new StringBuilder();
443
444 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700445 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
446 */
447 private boolean mPendingBroadcastTimeoutMessage;
448
449 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 * Intent broadcast that we have tried to start, but are
451 * waiting for its application's process to be created. We only
452 * need one (instead of a list) because we always process broadcasts
453 * one at a time, so no others can be started while waiting for this
454 * one.
455 */
456 BroadcastRecord mPendingBroadcast = null;
457
458 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700459 * The receiver index that is pending, to restart the broadcast if needed.
460 */
461 int mPendingBroadcastRecvIndex;
462
463 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800464 * Keeps track of all IIntentReceivers that have been registered for
465 * broadcasts. Hash keys are the receiver IBinder, hash value is
466 * a ReceiverList.
467 */
468 final HashMap mRegisteredReceivers = new HashMap();
469
470 /**
471 * Resolver for broadcast intents to registered receivers.
472 * Holds BroadcastFilter (subclass of IntentFilter).
473 */
474 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
475 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
476 @Override
477 protected boolean allowFilterResult(
478 BroadcastFilter filter, List<BroadcastFilter> dest) {
479 IBinder target = filter.receiverList.receiver.asBinder();
480 for (int i=dest.size()-1; i>=0; i--) {
481 if (dest.get(i).receiverList.receiver.asBinder() == target) {
482 return false;
483 }
484 }
485 return true;
486 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700487
488 @Override
489 protected String packageForFilter(BroadcastFilter filter) {
490 return filter.packageName;
491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 };
493
494 /**
495 * State of all active sticky broadcasts. Keys are the action of the
496 * sticky Intent, values are an ArrayList of all broadcasted intents with
497 * that action (which should usually be one).
498 */
499 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
500 new HashMap<String, ArrayList<Intent>>();
501
502 /**
503 * All currently running services.
504 */
505 final HashMap<ComponentName, ServiceRecord> mServices =
506 new HashMap<ComponentName, ServiceRecord>();
507
508 /**
509 * All currently running services indexed by the Intent used to start them.
510 */
511 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
512 new HashMap<Intent.FilterComparison, ServiceRecord>();
513
514 /**
515 * All currently bound service connections. Keys are the IBinder of
516 * the client's IServiceConnection.
517 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700518 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
519 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520
521 /**
522 * List of services that we have been asked to start,
523 * but haven't yet been able to. It is used to hold start requests
524 * while waiting for their corresponding application thread to get
525 * going.
526 */
527 final ArrayList<ServiceRecord> mPendingServices
528 = new ArrayList<ServiceRecord>();
529
530 /**
531 * List of services that are scheduled to restart following a crash.
532 */
533 final ArrayList<ServiceRecord> mRestartingServices
534 = new ArrayList<ServiceRecord>();
535
536 /**
537 * List of services that are in the process of being stopped.
538 */
539 final ArrayList<ServiceRecord> mStoppingServices
540 = new ArrayList<ServiceRecord>();
541
542 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700543 * Backup/restore process management
544 */
545 String mBackupAppName = null;
546 BackupRecord mBackupTarget = null;
547
548 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800549 * List of PendingThumbnailsRecord objects of clients who are still
550 * waiting to receive all of the thumbnails for a task.
551 */
552 final ArrayList mPendingThumbnails = new ArrayList();
553
554 /**
555 * List of HistoryRecord objects that have been finished and must
556 * still report back to a pending thumbnail receiver.
557 */
558 final ArrayList mCancelledThumbnails = new ArrayList();
559
560 /**
561 * All of the currently running global content providers. Keys are a
562 * string containing the provider name and values are a
563 * ContentProviderRecord object containing the data about it. Note
564 * that a single provider may be published under multiple names, so
565 * there may be multiple entries here for a single one in mProvidersByClass.
566 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700567 final HashMap<String, ContentProviderRecord> mProvidersByName
568 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569
570 /**
571 * All of the currently running global content providers. Keys are a
572 * string containing the provider's implementation class and values are a
573 * ContentProviderRecord object containing the data about it.
574 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700575 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
576 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800577
578 /**
579 * List of content providers who have clients waiting for them. The
580 * application is currently being launched and the provider will be
581 * removed from this list once it is published.
582 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700583 final ArrayList<ContentProviderRecord> mLaunchingProviders
584 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585
586 /**
587 * Global set of specific Uri permissions that have been granted.
588 */
589 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
590 = new SparseArray<HashMap<Uri, UriPermission>>();
591
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800592 CoreSettingsObserver mCoreSettingsObserver;
593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 /**
595 * Thread-local storage used to carry caller permissions over through
596 * indirect content-provider access.
597 * @see #ActivityManagerService.openContentUri()
598 */
599 private class Identity {
600 public int pid;
601 public int uid;
602
603 Identity(int _pid, int _uid) {
604 pid = _pid;
605 uid = _uid;
606 }
607 }
608 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
609
610 /**
611 * All information we have collected about the runtime performance of
612 * any user id that can impact battery performance.
613 */
614 final BatteryStatsService mBatteryStatsService;
615
616 /**
617 * information about component usage
618 */
619 final UsageStatsService mUsageStatsService;
620
621 /**
622 * Current configuration information. HistoryRecord objects are given
623 * a reference to this object to indicate which configuration they are
624 * currently running in, so this object must be kept immutable.
625 */
626 Configuration mConfiguration = new Configuration();
627
628 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800629 * Current sequencing integer of the configuration, for skipping old
630 * configurations.
631 */
632 int mConfigurationSeq = 0;
633
634 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700635 * Hardware-reported OpenGLES version.
636 */
637 final int GL_ES_VERSION;
638
639 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800640 * List of initialization arguments to pass to all processes when binding applications to them.
641 * For example, references to the commonly used services.
642 */
643 HashMap<String, IBinder> mAppBindArgs;
644
645 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700646 * Temporary to avoid allocations. Protected by main lock.
647 */
648 final StringBuilder mStringBuilder = new StringBuilder(256);
649
650 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800651 * Used to control how we initialize the service.
652 */
653 boolean mStartRunning = false;
654 ComponentName mTopComponent;
655 String mTopAction;
656 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700657 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 boolean mSystemReady = false;
659 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700660 boolean mWaitingUpdate = false;
661 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700662 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700663 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800664
665 Context mContext;
666
667 int mFactoryTest;
668
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700669 boolean mCheckedForSetup;
670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800671 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700672 * The time at which we will allow normal application switches again,
673 * after a call to {@link #stopAppSwitches()}.
674 */
675 long mAppSwitchesAllowedTime;
676
677 /**
678 * This is set to true after the first switch after mAppSwitchesAllowedTime
679 * is set; any switches after that will clear the time.
680 */
681 boolean mDidAppSwitch;
682
683 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700684 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700685 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700686 long mLastPowerCheckRealtime;
687
688 /**
689 * Last time (in uptime) at which we checked for power usage.
690 */
691 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700692
693 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 * Set while we are wanting to sleep, to prevent any
695 * activities from being started/resumed.
696 */
697 boolean mSleeping = false;
698
699 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700700 * Set if we are shutting down the system, similar to sleeping.
701 */
702 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703
704 /**
705 * Task identifier that activities are currently being started
706 * in. Incremented each time a new task is created.
707 * todo: Replace this with a TokenSpace class that generates non-repeating
708 * integers that won't wrap.
709 */
710 int mCurTask = 1;
711
712 /**
713 * Current sequence id for oom_adj computation traversal.
714 */
715 int mAdjSeq = 0;
716
717 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700718 * Current sequence id for process LRU updating.
719 */
720 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800721
722 /**
723 * System monitoring: number of processes that died since the last
724 * N procs were started.
725 */
726 int[] mProcDeaths = new int[20];
727
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700728 /**
729 * This is set if we had to do a delayed dexopt of an app before launching
730 * it, to increasing the ANR timeouts in that case.
731 */
732 boolean mDidDexOpt;
733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 String mDebugApp = null;
735 boolean mWaitForDebugger = false;
736 boolean mDebugTransient = false;
737 String mOrigDebugApp = null;
738 boolean mOrigWaitForDebugger = false;
739 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700740 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700741 String mProfileApp = null;
742 ProcessRecord mProfileProc = null;
743 String mProfileFile;
744 ParcelFileDescriptor mProfileFd;
745 int mProfileType = 0;
746 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800747
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700748 final RemoteCallbackList<IActivityWatcher> mWatchers
749 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700750
751 final RemoteCallbackList<IProcessObserver> mProcessObservers
752 = new RemoteCallbackList<IProcessObserver>();
753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 /**
755 * Callback of last caller to {@link #requestPss}.
756 */
757 Runnable mRequestPssCallback;
758
759 /**
760 * Remaining processes for which we are waiting results from the last
761 * call to {@link #requestPss}.
762 */
763 final ArrayList<ProcessRecord> mRequestPssList
764 = new ArrayList<ProcessRecord>();
765
766 /**
767 * Runtime statistics collection thread. This object's lock is used to
768 * protect all related state.
769 */
770 final Thread mProcessStatsThread;
771
772 /**
773 * Used to collect process stats when showing not responding dialog.
774 * Protected by mProcessStatsThread.
775 */
776 final ProcessStats mProcessStats = new ProcessStats(
777 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700778 final AtomicLong mLastCpuTime = new AtomicLong(0);
779 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 long mLastWriteTime = 0;
782
783 /**
784 * Set to true after the system has finished booting.
785 */
786 boolean mBooted = false;
787
Dianne Hackborn7d608422011-08-07 16:24:18 -0700788 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700789 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800790
791 WindowManagerService mWindowManager;
792
793 static ActivityManagerService mSelf;
794 static ActivityThread mSystemThread;
795
796 private final class AppDeathRecipient implements IBinder.DeathRecipient {
797 final ProcessRecord mApp;
798 final int mPid;
799 final IApplicationThread mAppThread;
800
801 AppDeathRecipient(ProcessRecord app, int pid,
802 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800803 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804 TAG, "New death recipient " + this
805 + " for thread " + thread.asBinder());
806 mApp = app;
807 mPid = pid;
808 mAppThread = thread;
809 }
810
811 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800812 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 TAG, "Death received in " + this
814 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 synchronized(ActivityManagerService.this) {
816 appDiedLocked(mApp, mPid, mAppThread);
817 }
818 }
819 }
820
821 static final int SHOW_ERROR_MSG = 1;
822 static final int SHOW_NOT_RESPONDING_MSG = 2;
823 static final int SHOW_FACTORY_ERROR_MSG = 3;
824 static final int UPDATE_CONFIGURATION_MSG = 4;
825 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
826 static final int WAIT_FOR_DEBUGGER_MSG = 6;
827 static final int BROADCAST_INTENT_MSG = 7;
828 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 static final int SERVICE_TIMEOUT_MSG = 12;
830 static final int UPDATE_TIME_ZONE = 13;
831 static final int SHOW_UID_ERROR_MSG = 14;
832 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800833 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700834 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700835 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800836 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700837 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
838 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700839 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700840 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700841 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700842 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700843 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700844 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
845 static final int DISPATCH_PROCESS_DIED = 32;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846
847 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700848 CompatModeDialog mCompatModeDialog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849
850 final Handler mHandler = new Handler() {
851 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800852 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 //}
854
855 public void handleMessage(Message msg) {
856 switch (msg.what) {
857 case SHOW_ERROR_MSG: {
858 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800859 synchronized (ActivityManagerService.this) {
860 ProcessRecord proc = (ProcessRecord)data.get("app");
861 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800862 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863 return;
864 }
865 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700866 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800867 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868 d.show();
869 proc.crashDialog = d;
870 } else {
871 // The device is asleep, so just pretend that the user
872 // saw a crash dialog and hit "force quit".
873 res.set(0);
874 }
875 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700876
877 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 } break;
879 case SHOW_NOT_RESPONDING_MSG: {
880 synchronized (ActivityManagerService.this) {
881 HashMap data = (HashMap) msg.obj;
882 ProcessRecord proc = (ProcessRecord)data.get("app");
883 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800884 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 return;
886 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800887
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700888 Intent intent = new Intent("android.intent.action.ANR");
889 if (!mProcessesReady) {
890 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
891 }
892 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800893 null, null, 0, null, null, null,
894 false, false, MY_PID, Process.SYSTEM_UID);
895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700897 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 d.show();
899 proc.anrDialog = d;
900 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700901
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700902 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700904 case SHOW_STRICT_MODE_VIOLATION_MSG: {
905 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
906 synchronized (ActivityManagerService.this) {
907 ProcessRecord proc = (ProcessRecord) data.get("app");
908 if (proc == null) {
909 Slog.e(TAG, "App not found when showing strict mode dialog.");
910 break;
911 }
912 if (proc.crashDialog != null) {
913 Slog.e(TAG, "App already has strict mode dialog: " + proc);
914 return;
915 }
916 AppErrorResult res = (AppErrorResult) data.get("result");
917 if (!mSleeping && !mShuttingDown) {
918 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
919 d.show();
920 proc.crashDialog = d;
921 } else {
922 // The device is asleep, so just pretend that the user
923 // saw a crash dialog and hit "force quit".
924 res.set(0);
925 }
926 }
927 ensureBootCompleted();
928 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800929 case SHOW_FACTORY_ERROR_MSG: {
930 Dialog d = new FactoryErrorDialog(
931 mContext, msg.getData().getCharSequence("msg"));
932 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700933 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 } break;
935 case UPDATE_CONFIGURATION_MSG: {
936 final ContentResolver resolver = mContext.getContentResolver();
937 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
938 } break;
939 case GC_BACKGROUND_PROCESSES_MSG: {
940 synchronized (ActivityManagerService.this) {
941 performAppGcsIfAppropriateLocked();
942 }
943 } break;
944 case WAIT_FOR_DEBUGGER_MSG: {
945 synchronized (ActivityManagerService.this) {
946 ProcessRecord app = (ProcessRecord)msg.obj;
947 if (msg.arg1 != 0) {
948 if (!app.waitedForDebugger) {
949 Dialog d = new AppWaitingForDebuggerDialog(
950 ActivityManagerService.this,
951 mContext, app);
952 app.waitDialog = d;
953 app.waitedForDebugger = true;
954 d.show();
955 }
956 } else {
957 if (app.waitDialog != null) {
958 app.waitDialog.dismiss();
959 app.waitDialog = null;
960 }
961 }
962 }
963 } break;
964 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800965 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 TAG, "Received BROADCAST_INTENT_MSG");
967 processNextBroadcast(true);
968 } break;
969 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700970 synchronized (ActivityManagerService.this) {
971 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700975 if (mDidDexOpt) {
976 mDidDexOpt = false;
977 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
978 nmsg.obj = msg.obj;
979 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
980 return;
981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 serviceTimeout((ProcessRecord)msg.obj);
983 } break;
984 case UPDATE_TIME_ZONE: {
985 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800986 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
987 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 if (r.thread != null) {
989 try {
990 r.thread.updateTimeZone();
991 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800992 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 }
994 }
995 }
996 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700997 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700998 case CLEAR_DNS_CACHE: {
999 synchronized (ActivityManagerService.this) {
1000 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1001 ProcessRecord r = mLruProcesses.get(i);
1002 if (r.thread != null) {
1003 try {
1004 r.thread.clearDnsCache();
1005 } catch (RemoteException ex) {
1006 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1007 }
1008 }
1009 }
1010 }
1011 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001012 case UPDATE_HTTP_PROXY: {
1013 ProxyProperties proxy = (ProxyProperties)msg.obj;
1014 String host = "";
1015 String port = "";
1016 String exclList = "";
1017 if (proxy != null) {
1018 host = proxy.getHost();
1019 port = Integer.toString(proxy.getPort());
1020 exclList = proxy.getExclusionList();
1021 }
1022 synchronized (ActivityManagerService.this) {
1023 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1024 ProcessRecord r = mLruProcesses.get(i);
1025 if (r.thread != null) {
1026 try {
1027 r.thread.setHttpProxy(host, port, exclList);
1028 } catch (RemoteException ex) {
1029 Slog.w(TAG, "Failed to update http proxy for: " +
1030 r.info.processName);
1031 }
1032 }
1033 }
1034 }
1035 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001036 case SHOW_UID_ERROR_MSG: {
1037 // XXX This is a temporary dialog, no need to localize.
1038 AlertDialog d = new BaseErrorDialog(mContext);
1039 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1040 d.setCancelable(false);
1041 d.setTitle("System UIDs Inconsistent");
1042 d.setMessage("UIDs on the system are inconsistent, you need to wipe your data partition or your device will be unstable.");
Christian Mehlmauer7664e202010-07-20 08:46:17 +02001043 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1045 mUidAlert = d;
1046 d.show();
1047 } break;
1048 case IM_FEELING_LUCKY_MSG: {
1049 if (mUidAlert != null) {
1050 mUidAlert.dismiss();
1051 mUidAlert = null;
1052 }
1053 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001055 if (mDidDexOpt) {
1056 mDidDexOpt = false;
1057 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1058 nmsg.obj = msg.obj;
1059 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1060 return;
1061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 ProcessRecord app = (ProcessRecord)msg.obj;
1063 synchronized (ActivityManagerService.this) {
1064 processStartTimedOutLocked(app);
1065 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001066 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001067 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1068 synchronized (ActivityManagerService.this) {
1069 doPendingActivityLaunchesLocked(true);
1070 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001071 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001072 case KILL_APPLICATION_MSG: {
1073 synchronized (ActivityManagerService.this) {
1074 int uid = msg.arg1;
1075 boolean restart = (msg.arg2 == 1);
1076 String pkg = (String) msg.obj;
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 Hackborn661cd522011-08-22 00:26:20 -07003751 public void showBootMessage(final CharSequence msg, final boolean always) {
3752 mWindowManager.showBootMessage(msg, always);
3753 }
3754
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003755 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003756 IntentFilter pkgFilter = new IntentFilter();
3757 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3758 pkgFilter.addDataScheme("package");
3759 mContext.registerReceiver(new BroadcastReceiver() {
3760 @Override
3761 public void onReceive(Context context, Intent intent) {
3762 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3763 if (pkgs != null) {
3764 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003765 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003766 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003767 setResultCode(Activity.RESULT_OK);
3768 return;
3769 }
3770 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003771 }
3772 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003773 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003774 }, pkgFilter);
3775
3776 synchronized (this) {
3777 // Ensure that any processes we had put on hold are now started
3778 // up.
3779 final int NP = mProcessesOnHold.size();
3780 if (NP > 0) {
3781 ArrayList<ProcessRecord> procs =
3782 new ArrayList<ProcessRecord>(mProcessesOnHold);
3783 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003784 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
3785 + procs.get(ip));
3786 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003787 }
3788 }
3789
3790 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003791 // Start looking for apps that are abusing wake locks.
3792 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003793 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003794 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07003795 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003796 broadcastIntentLocked(null, null,
3797 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
3798 null, null, 0, null, null,
3799 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
3800 false, false, MY_PID, Process.SYSTEM_UID);
3801 }
3802 }
3803 }
3804
3805 final void ensureBootCompleted() {
3806 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003807 boolean enableScreen;
3808 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003809 booting = mBooting;
3810 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003811 enableScreen = !mBooted;
3812 mBooted = true;
3813 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003814
3815 if (booting) {
3816 finishBooting();
3817 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003818
3819 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07003820 enableScreenAfterBoot();
3821 }
3822 }
3823
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003824 public final void activityPaused(IBinder token) {
3825 final long origId = Binder.clearCallingIdentity();
3826 mMainStack.activityPaused(token, false);
3827 Binder.restoreCallingIdentity(origId);
3828 }
3829
3830 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
3831 CharSequence description) {
3832 if (localLOGV) Slog.v(
3833 TAG, "Activity stopped: token=" + token);
3834
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003835 // Refuse possible leaked file descriptors
3836 if (icicle != null && icicle.hasFileDescriptors()) {
3837 throw new IllegalArgumentException("File descriptors passed in Bundle");
3838 }
3839
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003840 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003841
3842 final long origId = Binder.clearCallingIdentity();
3843
3844 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003845 r = mMainStack.isInStackLocked(token);
3846 if (r != null) {
3847 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003848 }
3849 }
3850
3851 if (r != null) {
3852 sendPendingThumbnail(r, null, null, null, false);
3853 }
3854
3855 trimApplications();
3856
3857 Binder.restoreCallingIdentity(origId);
3858 }
3859
3860 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003861 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003862 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003863 }
3864
3865 public String getCallingPackage(IBinder token) {
3866 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003867 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07003868 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003869 }
3870 }
3871
3872 public ComponentName getCallingActivity(IBinder token) {
3873 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003874 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003875 return r != null ? r.intent.getComponent() : null;
3876 }
3877 }
3878
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003879 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003880 ActivityRecord r = mMainStack.isInStackLocked(token);
3881 if (r == null) {
3882 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003883 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003884 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003885 }
3886
3887 public ComponentName getActivityClassForToken(IBinder token) {
3888 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003889 ActivityRecord r = mMainStack.isInStackLocked(token);
3890 if (r == null) {
3891 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003892 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003893 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 }
3895 }
3896
3897 public String getPackageForToken(IBinder token) {
3898 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003899 ActivityRecord r = mMainStack.isInStackLocked(token);
3900 if (r == null) {
3901 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003903 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 }
3905 }
3906
3907 public IIntentSender getIntentSender(int type,
3908 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003909 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003910 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003911 if (intents != null) {
3912 if (intents.length < 1) {
3913 throw new IllegalArgumentException("Intents array length must be >= 1");
3914 }
3915 for (int i=0; i<intents.length; i++) {
3916 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07003917 if (intent != null) {
3918 if (intent.hasFileDescriptors()) {
3919 throw new IllegalArgumentException("File descriptors passed in Intent");
3920 }
3921 if (type == INTENT_SENDER_BROADCAST &&
3922 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
3923 throw new IllegalArgumentException(
3924 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
3925 }
3926 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003927 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003928 }
3929 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003930 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003931 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003932 }
3933 }
3934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 synchronized(this) {
3936 int callingUid = Binder.getCallingUid();
3937 try {
Jeff Brown10e89712011-07-08 18:52:57 -07003938 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003939 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 .getPackageUid(packageName);
3941 if (uid != Binder.getCallingUid()) {
3942 String msg = "Permission Denial: getIntentSender() from pid="
3943 + Binder.getCallingPid()
3944 + ", uid=" + Binder.getCallingUid()
3945 + ", (need uid=" + uid + ")"
3946 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003947 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003948 throw new SecurityException(msg);
3949 }
3950 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003951
3952 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003953 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003955 } catch (RemoteException e) {
3956 throw new SecurityException(e);
3957 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003958 }
3959 }
3960
3961 IIntentSender getIntentSenderLocked(int type,
3962 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003963 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003964 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003965 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003966 activity = mMainStack.isInStackLocked(token);
3967 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07003968 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003970 if (activity.finishing) {
3971 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003972 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07003973 }
3974
3975 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
3976 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
3977 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
3978 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
3979 |PendingIntent.FLAG_UPDATE_CURRENT);
3980
3981 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
3982 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003983 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003984 WeakReference<PendingIntentRecord> ref;
3985 ref = mIntentSenderRecords.get(key);
3986 PendingIntentRecord rec = ref != null ? ref.get() : null;
3987 if (rec != null) {
3988 if (!cancelCurrent) {
3989 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08003990 if (rec.key.requestIntent != null) {
3991 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
3992 }
3993 if (intents != null) {
3994 intents[intents.length-1] = rec.key.requestIntent;
3995 rec.key.allIntents = intents;
3996 rec.key.allResolvedTypes = resolvedTypes;
3997 } else {
3998 rec.key.allIntents = null;
3999 rec.key.allResolvedTypes = null;
4000 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004002 return rec;
4003 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004004 rec.canceled = true;
4005 mIntentSenderRecords.remove(key);
4006 }
4007 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004008 return rec;
4009 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004010 rec = new PendingIntentRecord(this, key, callingUid);
4011 mIntentSenderRecords.put(key, rec.ref);
4012 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4013 if (activity.pendingResults == null) {
4014 activity.pendingResults
4015 = new HashSet<WeakReference<PendingIntentRecord>>();
4016 }
4017 activity.pendingResults.add(rec.ref);
4018 }
4019 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004020 }
4021
4022 public void cancelIntentSender(IIntentSender sender) {
4023 if (!(sender instanceof PendingIntentRecord)) {
4024 return;
4025 }
4026 synchronized(this) {
4027 PendingIntentRecord rec = (PendingIntentRecord)sender;
4028 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004029 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004030 .getPackageUid(rec.key.packageName);
4031 if (uid != Binder.getCallingUid()) {
4032 String msg = "Permission Denial: cancelIntentSender() from pid="
4033 + Binder.getCallingPid()
4034 + ", uid=" + Binder.getCallingUid()
4035 + " is not allowed to cancel packges "
4036 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004037 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004038 throw new SecurityException(msg);
4039 }
4040 } catch (RemoteException e) {
4041 throw new SecurityException(e);
4042 }
4043 cancelIntentSenderLocked(rec, true);
4044 }
4045 }
4046
4047 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4048 rec.canceled = true;
4049 mIntentSenderRecords.remove(rec.key);
4050 if (cleanActivity && rec.key.activity != null) {
4051 rec.key.activity.pendingResults.remove(rec.ref);
4052 }
4053 }
4054
4055 public String getPackageForIntentSender(IIntentSender pendingResult) {
4056 if (!(pendingResult instanceof PendingIntentRecord)) {
4057 return null;
4058 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004059 try {
4060 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4061 return res.key.packageName;
4062 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 }
4064 return null;
4065 }
4066
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004067 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4068 if (!(pendingResult instanceof PendingIntentRecord)) {
4069 return false;
4070 }
4071 try {
4072 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4073 if (res.key.allIntents == null) {
4074 return false;
4075 }
4076 for (int i=0; i<res.key.allIntents.length; i++) {
4077 Intent intent = res.key.allIntents[i];
4078 if (intent.getPackage() != null && intent.getComponent() != null) {
4079 return false;
4080 }
4081 }
4082 return true;
4083 } catch (ClassCastException e) {
4084 }
4085 return false;
4086 }
4087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004088 public void setProcessLimit(int max) {
4089 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4090 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004091 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004092 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004093 mProcessLimitOverride = max;
4094 }
4095 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 }
4097
4098 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004099 synchronized (this) {
4100 return mProcessLimitOverride;
4101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 }
4103
4104 void foregroundTokenDied(ForegroundToken token) {
4105 synchronized (ActivityManagerService.this) {
4106 synchronized (mPidsSelfLocked) {
4107 ForegroundToken cur
4108 = mForegroundProcesses.get(token.pid);
4109 if (cur != token) {
4110 return;
4111 }
4112 mForegroundProcesses.remove(token.pid);
4113 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4114 if (pr == null) {
4115 return;
4116 }
4117 pr.forcingToForeground = null;
4118 pr.foregroundServices = false;
4119 }
4120 updateOomAdjLocked();
4121 }
4122 }
4123
4124 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4125 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4126 "setProcessForeground()");
4127 synchronized(this) {
4128 boolean changed = false;
4129
4130 synchronized (mPidsSelfLocked) {
4131 ProcessRecord pr = mPidsSelfLocked.get(pid);
4132 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004133 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004134 return;
4135 }
4136 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4137 if (oldToken != null) {
4138 oldToken.token.unlinkToDeath(oldToken, 0);
4139 mForegroundProcesses.remove(pid);
4140 pr.forcingToForeground = null;
4141 changed = true;
4142 }
4143 if (isForeground && token != null) {
4144 ForegroundToken newToken = new ForegroundToken() {
4145 public void binderDied() {
4146 foregroundTokenDied(this);
4147 }
4148 };
4149 newToken.pid = pid;
4150 newToken.token = token;
4151 try {
4152 token.linkToDeath(newToken, 0);
4153 mForegroundProcesses.put(pid, newToken);
4154 pr.forcingToForeground = token;
4155 changed = true;
4156 } catch (RemoteException e) {
4157 // If the process died while doing this, we will later
4158 // do the cleanup with the process death link.
4159 }
4160 }
4161 }
4162
4163 if (changed) {
4164 updateOomAdjLocked();
4165 }
4166 }
4167 }
4168
4169 // =========================================================
4170 // PERMISSIONS
4171 // =========================================================
4172
4173 static class PermissionController extends IPermissionController.Stub {
4174 ActivityManagerService mActivityManagerService;
4175 PermissionController(ActivityManagerService activityManagerService) {
4176 mActivityManagerService = activityManagerService;
4177 }
4178
4179 public boolean checkPermission(String permission, int pid, int uid) {
4180 return mActivityManagerService.checkPermission(permission, pid,
4181 uid) == PackageManager.PERMISSION_GRANTED;
4182 }
4183 }
4184
4185 /**
4186 * This can be called with or without the global lock held.
4187 */
4188 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004189 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004190 // We might be performing an operation on behalf of an indirect binder
4191 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4192 // client identity accordingly before proceeding.
4193 Identity tlsIdentity = sCallerIdentity.get();
4194 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004195 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004196 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4197 uid = tlsIdentity.uid;
4198 pid = tlsIdentity.pid;
4199 }
4200
4201 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004202 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004203 return PackageManager.PERMISSION_GRANTED;
4204 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004205 // If there is a uid that owns whatever is being accessed, it has
4206 // blanket access to it regardless of the permissions it requires.
4207 if (owningUid >= 0 && uid == owningUid) {
4208 return PackageManager.PERMISSION_GRANTED;
4209 }
4210 // If the target is not exported, then nobody else can get to it.
4211 if (!exported) {
4212 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004213 return PackageManager.PERMISSION_DENIED;
4214 }
4215 if (permission == null) {
4216 return PackageManager.PERMISSION_GRANTED;
4217 }
4218 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004219 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004220 .checkUidPermission(permission, uid);
4221 } catch (RemoteException e) {
4222 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004223 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 }
4225 return PackageManager.PERMISSION_DENIED;
4226 }
4227
4228 /**
4229 * As the only public entry point for permissions checking, this method
4230 * can enforce the semantic that requesting a check on a null global
4231 * permission is automatically denied. (Internally a null permission
4232 * string is used when calling {@link #checkComponentPermission} in cases
4233 * when only uid-based security is needed.)
4234 *
4235 * This can be called with or without the global lock held.
4236 */
4237 public int checkPermission(String permission, int pid, int uid) {
4238 if (permission == null) {
4239 return PackageManager.PERMISSION_DENIED;
4240 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004241 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
4243
4244 /**
4245 * Binder IPC calls go through the public entry point.
4246 * This can be called with or without the global lock held.
4247 */
4248 int checkCallingPermission(String permission) {
4249 return checkPermission(permission,
4250 Binder.getCallingPid(),
4251 Binder.getCallingUid());
4252 }
4253
4254 /**
4255 * This can be called with or without the global lock held.
4256 */
4257 void enforceCallingPermission(String permission, String func) {
4258 if (checkCallingPermission(permission)
4259 == PackageManager.PERMISSION_GRANTED) {
4260 return;
4261 }
4262
4263 String msg = "Permission Denial: " + func + " from pid="
4264 + Binder.getCallingPid()
4265 + ", uid=" + Binder.getCallingUid()
4266 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004267 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 throw new SecurityException(msg);
4269 }
4270
4271 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004272 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4273 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4274 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4275 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4276 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004277 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004278 // Is the component private from the target uid?
4279 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4280
4281 // Acceptable if the there is no read permission needed from the
4282 // target or the target is holding the read permission.
4283 if (!readPerm) {
4284 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004285 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004286 == PackageManager.PERMISSION_GRANTED)) {
4287 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 }
4289 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004290
4291 // Acceptable if the there is no write permission needed from the
4292 // target or the target is holding the read permission.
4293 if (!writePerm) {
4294 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004295 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004296 == PackageManager.PERMISSION_GRANTED)) {
4297 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 }
4299 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004300
4301 // Acceptable if there is a path permission matching the URI that
4302 // the target holds the permission on.
4303 PathPermission[] pps = pi.pathPermissions;
4304 if (pps != null && (!readPerm || !writePerm)) {
4305 final String path = uri.getPath();
4306 int i = pps.length;
4307 while (i > 0 && (!readPerm || !writePerm)) {
4308 i--;
4309 PathPermission pp = pps[i];
4310 if (!readPerm) {
4311 final String pprperm = pp.getReadPermission();
4312 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4313 + pprperm + " for " + pp.getPath()
4314 + ": match=" + pp.match(path)
4315 + " check=" + pm.checkUidPermission(pprperm, uid));
4316 if (pprperm != null && pp.match(path) &&
4317 (pm.checkUidPermission(pprperm, uid)
4318 == PackageManager.PERMISSION_GRANTED)) {
4319 readPerm = true;
4320 }
4321 }
4322 if (!writePerm) {
4323 final String ppwperm = pp.getWritePermission();
4324 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4325 + ppwperm + " for " + pp.getPath()
4326 + ": match=" + pp.match(path)
4327 + " check=" + pm.checkUidPermission(ppwperm, uid));
4328 if (ppwperm != null && pp.match(path) &&
4329 (pm.checkUidPermission(ppwperm, uid)
4330 == PackageManager.PERMISSION_GRANTED)) {
4331 writePerm = true;
4332 }
4333 }
4334 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336 } catch (RemoteException e) {
4337 return false;
4338 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004339
4340 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004341 }
4342
4343 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4344 int modeFlags) {
4345 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004346 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004347 return true;
4348 }
4349 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4350 if (perms == null) return false;
4351 UriPermission perm = perms.get(uri);
4352 if (perm == null) return false;
4353 return (modeFlags&perm.modeFlags) == modeFlags;
4354 }
4355
4356 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4357 // Another redirected-binder-call permissions check as in
4358 // {@link checkComponentPermission}.
4359 Identity tlsIdentity = sCallerIdentity.get();
4360 if (tlsIdentity != null) {
4361 uid = tlsIdentity.uid;
4362 pid = tlsIdentity.pid;
4363 }
4364
4365 // Our own process gets to do everything.
4366 if (pid == MY_PID) {
4367 return PackageManager.PERMISSION_GRANTED;
4368 }
4369 synchronized(this) {
4370 return checkUriPermissionLocked(uri, uid, modeFlags)
4371 ? PackageManager.PERMISSION_GRANTED
4372 : PackageManager.PERMISSION_DENIED;
4373 }
4374 }
4375
Dianne Hackborn39792d22010-08-19 18:01:52 -07004376 /**
4377 * Check if the targetPkg can be granted permission to access uri by
4378 * the callingUid using the given modeFlags. Throws a security exception
4379 * if callingUid is not allowed to do this. Returns the uid of the target
4380 * if the URI permission grant should be performed; returns -1 if it is not
4381 * needed (for example targetPkg already has permission to access the URI).
4382 */
4383 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4384 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4386 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4387 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004388 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004389 }
4390
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004391 if (targetPkg != null) {
4392 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4393 "Checking grant " + targetPkg + " permission to " + uri);
4394 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004395
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004396 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397
4398 // If this is not a content: uri, we can't do anything with it.
4399 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004400 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004401 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004402 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 }
4404
4405 String name = uri.getAuthority();
4406 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004407 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408 if (cpr != null) {
4409 pi = cpr.info;
4410 } else {
4411 try {
4412 pi = pm.resolveContentProvider(name,
4413 PackageManager.GET_URI_PERMISSION_PATTERNS);
4414 } catch (RemoteException ex) {
4415 }
4416 }
4417 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004418 Slog.w(TAG, "No content provider found for: " + name);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004419 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004420 }
4421
4422 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004423 if (targetPkg != null) {
4424 try {
4425 targetUid = pm.getPackageUid(targetPkg);
4426 if (targetUid < 0) {
4427 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4428 "Can't grant URI permission no uid for: " + targetPkg);
4429 return -1;
4430 }
4431 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004432 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004433 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004434 } else {
4435 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 }
4437
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004438 if (targetUid >= 0) {
4439 // First... does the target actually need this permission?
4440 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4441 // No need to grant the target this permission.
4442 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4443 "Target " + targetPkg + " already has full permission to " + uri);
4444 return -1;
4445 }
4446 } else {
4447 // First... there is no target package, so can anyone access it?
4448 boolean allowed = pi.exported;
4449 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4450 if (pi.readPermission != null) {
4451 allowed = false;
4452 }
4453 }
4454 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4455 if (pi.writePermission != null) {
4456 allowed = false;
4457 }
4458 }
4459 if (allowed) {
4460 return -1;
4461 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004462 }
4463
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004464 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004465 if (!pi.grantUriPermissions) {
4466 throw new SecurityException("Provider " + pi.packageName
4467 + "/" + pi.name
4468 + " does not allow granting of Uri permissions (uri "
4469 + uri + ")");
4470 }
4471 if (pi.uriPermissionPatterns != null) {
4472 final int N = pi.uriPermissionPatterns.length;
4473 boolean allowed = false;
4474 for (int i=0; i<N; i++) {
4475 if (pi.uriPermissionPatterns[i] != null
4476 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4477 allowed = true;
4478 break;
4479 }
4480 }
4481 if (!allowed) {
4482 throw new SecurityException("Provider " + pi.packageName
4483 + "/" + pi.name
4484 + " does not allow granting of permission to path of Uri "
4485 + uri);
4486 }
4487 }
4488
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004489 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004491 if (callingUid != Process.myUid()) {
4492 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4493 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4494 throw new SecurityException("Uid " + callingUid
4495 + " does not have permission to uri " + uri);
4496 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004497 }
4498 }
4499
Dianne Hackborn39792d22010-08-19 18:01:52 -07004500 return targetUid;
4501 }
4502
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004503 public int checkGrantUriPermission(int callingUid, String targetPkg,
4504 Uri uri, int modeFlags) {
4505 synchronized(this) {
4506 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4507 }
4508 }
4509
Dianne Hackborn39792d22010-08-19 18:01:52 -07004510 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4511 Uri uri, int modeFlags, UriPermissionOwner owner) {
4512 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4513 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4514 if (modeFlags == 0) {
4515 return;
4516 }
4517
4518 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 // to the uri, and the target doesn't. Let's now give this to
4520 // the target.
4521
Joe Onorato8a9b2202010-02-26 18:56:32 -08004522 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004523 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 HashMap<Uri, UriPermission> targetUris
4526 = mGrantedUriPermissions.get(targetUid);
4527 if (targetUris == null) {
4528 targetUris = new HashMap<Uri, UriPermission>();
4529 mGrantedUriPermissions.put(targetUid, targetUris);
4530 }
4531
4532 UriPermission perm = targetUris.get(uri);
4533 if (perm == null) {
4534 perm = new UriPermission(targetUid, uri);
4535 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004536 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004538 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004539 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004540 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004541 } else {
4542 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4543 perm.readOwners.add(owner);
4544 owner.addReadPermission(perm);
4545 }
4546 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4547 perm.writeOwners.add(owner);
4548 owner.addWritePermission(perm);
4549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004550 }
4551 }
4552
Dianne Hackborn39792d22010-08-19 18:01:52 -07004553 void grantUriPermissionLocked(int callingUid,
4554 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004555 if (targetPkg == null) {
4556 throw new NullPointerException("targetPkg");
4557 }
4558
Dianne Hackborn39792d22010-08-19 18:01:52 -07004559 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4560 if (targetUid < 0) {
4561 return;
4562 }
4563
4564 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4565 }
4566
4567 /**
4568 * Like checkGrantUriPermissionLocked, but takes an Intent.
4569 */
4570 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4571 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004572 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004573 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004574 + " from " + intent + "; flags=0x"
4575 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4576
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004577 if (targetPkg == null) {
4578 throw new NullPointerException("targetPkg");
4579 }
4580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004582 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004583 }
4584 Uri data = intent.getData();
4585 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004586 return -1;
4587 }
4588 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4589 intent.getFlags());
4590 }
4591
4592 /**
4593 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4594 */
4595 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4596 String targetPkg, Intent intent, UriPermissionOwner owner) {
4597 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4598 intent.getFlags(), owner);
4599 }
4600
4601 void grantUriPermissionFromIntentLocked(int callingUid,
4602 String targetPkg, Intent intent, UriPermissionOwner owner) {
4603 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4604 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004605 return;
4606 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004607
4608 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 }
4610
4611 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4612 Uri uri, int modeFlags) {
4613 synchronized(this) {
4614 final ProcessRecord r = getRecordForAppLocked(caller);
4615 if (r == null) {
4616 throw new SecurityException("Unable to find app for caller "
4617 + caller
4618 + " when granting permission to uri " + uri);
4619 }
4620 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004621 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 }
4623 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004624 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 }
4626
4627 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4628 null);
4629 }
4630 }
4631
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004632 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004633 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4634 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4635 HashMap<Uri, UriPermission> perms
4636 = mGrantedUriPermissions.get(perm.uid);
4637 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004638 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004639 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 perms.remove(perm.uri);
4641 if (perms.size() == 0) {
4642 mGrantedUriPermissions.remove(perm.uid);
4643 }
4644 }
4645 }
4646 }
4647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004648 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4649 int modeFlags) {
4650 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4651 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4652 if (modeFlags == 0) {
4653 return;
4654 }
4655
Joe Onorato8a9b2202010-02-26 18:56:32 -08004656 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004657 "Revoking all granted permissions to " + uri);
4658
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004659 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660
4661 final String authority = uri.getAuthority();
4662 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004663 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664 if (cpr != null) {
4665 pi = cpr.info;
4666 } else {
4667 try {
4668 pi = pm.resolveContentProvider(authority,
4669 PackageManager.GET_URI_PERMISSION_PATTERNS);
4670 } catch (RemoteException ex) {
4671 }
4672 }
4673 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004674 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004675 return;
4676 }
4677
4678 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004679 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 // Right now, if you are not the original owner of the permission,
4681 // you are not allowed to revoke it.
4682 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4683 throw new SecurityException("Uid " + callingUid
4684 + " does not have permission to uri " + uri);
4685 //}
4686 }
4687
4688 // Go through all of the permissions and remove any that match.
4689 final List<String> SEGMENTS = uri.getPathSegments();
4690 if (SEGMENTS != null) {
4691 final int NS = SEGMENTS.size();
4692 int N = mGrantedUriPermissions.size();
4693 for (int i=0; i<N; i++) {
4694 HashMap<Uri, UriPermission> perms
4695 = mGrantedUriPermissions.valueAt(i);
4696 Iterator<UriPermission> it = perms.values().iterator();
4697 toploop:
4698 while (it.hasNext()) {
4699 UriPermission perm = it.next();
4700 Uri targetUri = perm.uri;
4701 if (!authority.equals(targetUri.getAuthority())) {
4702 continue;
4703 }
4704 List<String> targetSegments = targetUri.getPathSegments();
4705 if (targetSegments == null) {
4706 continue;
4707 }
4708 if (targetSegments.size() < NS) {
4709 continue;
4710 }
4711 for (int j=0; j<NS; j++) {
4712 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4713 continue toploop;
4714 }
4715 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004716 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004717 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004718 perm.clearModes(modeFlags);
4719 if (perm.modeFlags == 0) {
4720 it.remove();
4721 }
4722 }
4723 if (perms.size() == 0) {
4724 mGrantedUriPermissions.remove(
4725 mGrantedUriPermissions.keyAt(i));
4726 N--;
4727 i--;
4728 }
4729 }
4730 }
4731 }
4732
4733 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4734 int modeFlags) {
4735 synchronized(this) {
4736 final ProcessRecord r = getRecordForAppLocked(caller);
4737 if (r == null) {
4738 throw new SecurityException("Unable to find app for caller "
4739 + caller
4740 + " when revoking permission to uri " + uri);
4741 }
4742 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004743 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004744 return;
4745 }
4746
4747 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4748 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4749 if (modeFlags == 0) {
4750 return;
4751 }
4752
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004753 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754
4755 final String authority = uri.getAuthority();
4756 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004757 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004758 if (cpr != null) {
4759 pi = cpr.info;
4760 } else {
4761 try {
4762 pi = pm.resolveContentProvider(authority,
4763 PackageManager.GET_URI_PERMISSION_PATTERNS);
4764 } catch (RemoteException ex) {
4765 }
4766 }
4767 if (pi == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004768 Slog.w(TAG, "No content provider found for: " + authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004769 return;
4770 }
4771
4772 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4773 }
4774 }
4775
Dianne Hackborn7e269642010-08-25 19:50:20 -07004776 @Override
4777 public IBinder newUriPermissionOwner(String name) {
4778 synchronized(this) {
4779 UriPermissionOwner owner = new UriPermissionOwner(this, name);
4780 return owner.getExternalTokenLocked();
4781 }
4782 }
4783
4784 @Override
4785 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
4786 Uri uri, int modeFlags) {
4787 synchronized(this) {
4788 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4789 if (owner == null) {
4790 throw new IllegalArgumentException("Unknown owner: " + token);
4791 }
4792 if (fromUid != Binder.getCallingUid()) {
4793 if (Binder.getCallingUid() != Process.myUid()) {
4794 // Only system code can grant URI permissions on behalf
4795 // of other users.
4796 throw new SecurityException("nice try");
4797 }
4798 }
4799 if (targetPkg == null) {
4800 throw new IllegalArgumentException("null target");
4801 }
4802 if (uri == null) {
4803 throw new IllegalArgumentException("null uri");
4804 }
4805
4806 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
4807 }
4808 }
4809
4810 @Override
4811 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
4812 synchronized(this) {
4813 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
4814 if (owner == null) {
4815 throw new IllegalArgumentException("Unknown owner: " + token);
4816 }
4817
4818 if (uri == null) {
4819 owner.removeUriPermissionsLocked(mode);
4820 } else {
4821 owner.removeUriPermissionLocked(uri, mode);
4822 }
4823 }
4824 }
4825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004826 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
4827 synchronized (this) {
4828 ProcessRecord app =
4829 who != null ? getRecordForAppLocked(who) : null;
4830 if (app == null) return;
4831
4832 Message msg = Message.obtain();
4833 msg.what = WAIT_FOR_DEBUGGER_MSG;
4834 msg.obj = app;
4835 msg.arg1 = waiting ? 1 : 0;
4836 mHandler.sendMessage(msg);
4837 }
4838 }
4839
4840 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004841 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
4842 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004843 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07004844 outInfo.threshold = homeAppMem;
4845 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
4846 outInfo.hiddenAppThreshold = hiddenAppMem;
4847 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
4848 ProcessList.SECONDARY_SERVER_ADJ);
4849 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
4850 ProcessList.VISIBLE_APP_ADJ);
4851 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
4852 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004853 }
4854
4855 // =========================================================
4856 // TASK MANAGEMENT
4857 // =========================================================
4858
4859 public List getTasks(int maxNum, int flags,
4860 IThumbnailReceiver receiver) {
4861 ArrayList list = new ArrayList();
4862
4863 PendingThumbnailsRecord pending = null;
4864 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004865 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004866
4867 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004868 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004869 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
4870 + ", receiver=" + receiver);
4871
4872 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
4873 != PackageManager.PERMISSION_GRANTED) {
4874 if (receiver != null) {
4875 // If the caller wants to wait for pending thumbnails,
4876 // it ain't gonna get them.
4877 try {
4878 receiver.finished();
4879 } catch (RemoteException ex) {
4880 }
4881 }
4882 String msg = "Permission Denial: getTasks() from pid="
4883 + Binder.getCallingPid()
4884 + ", uid=" + Binder.getCallingUid()
4885 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004886 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004887 throw new SecurityException(msg);
4888 }
4889
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004890 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004891 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004892 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004893 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 TaskRecord curTask = null;
4895 int numActivities = 0;
4896 int numRunning = 0;
4897 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004898 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004899 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004900 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901
4902 // Initialize state for next task if needed.
4903 if (top == null ||
4904 (top.state == ActivityState.INITIALIZING
4905 && top.task == r.task)) {
4906 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 curTask = r.task;
4908 numActivities = numRunning = 0;
4909 }
4910
4911 // Add 'r' into the current task.
4912 numActivities++;
4913 if (r.app != null && r.app.thread != null) {
4914 numRunning++;
4915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004916
Joe Onorato8a9b2202010-02-26 18:56:32 -08004917 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004918 TAG, r.intent.getComponent().flattenToShortString()
4919 + ": task=" + r.task);
4920
4921 // If the next one is a different task, generate a new
4922 // TaskInfo entry for what we have.
4923 if (next == null || next.task != curTask) {
4924 ActivityManager.RunningTaskInfo ci
4925 = new ActivityManager.RunningTaskInfo();
4926 ci.id = curTask.taskId;
4927 ci.baseActivity = r.intent.getComponent();
4928 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07004929 if (top.thumbHolder != null) {
4930 ci.description = top.thumbHolder.lastDescription;
4931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004932 ci.numActivities = numActivities;
4933 ci.numRunning = numRunning;
4934 //System.out.println(
4935 // "#" + maxNum + ": " + " descr=" + ci.description);
4936 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004937 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004938 TAG, "State=" + top.state + "Idle=" + top.idle
4939 + " app=" + top.app
4940 + " thr=" + (top.app != null ? top.app.thread : null));
4941 if (top.state == ActivityState.RESUMED
4942 || top.state == ActivityState.PAUSING) {
4943 if (top.idle && top.app != null
4944 && top.app.thread != null) {
4945 topRecord = top;
4946 topThumbnail = top.app.thread;
4947 } else {
4948 top.thumbnailNeeded = true;
4949 }
4950 }
4951 if (pending == null) {
4952 pending = new PendingThumbnailsRecord(receiver);
4953 }
4954 pending.pendingRecords.add(top);
4955 }
4956 list.add(ci);
4957 maxNum--;
4958 top = null;
4959 }
4960 }
4961
4962 if (pending != null) {
4963 mPendingThumbnails.add(pending);
4964 }
4965 }
4966
Joe Onorato8a9b2202010-02-26 18:56:32 -08004967 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004968
4969 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004970 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 try {
4972 topThumbnail.requestThumbnail(topRecord);
4973 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004974 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004975 sendPendingThumbnail(null, topRecord, null, null, true);
4976 }
4977 }
4978
4979 if (pending == null && receiver != null) {
4980 // In this case all thumbnails were available and the client
4981 // is being asked to be told when the remaining ones come in...
4982 // which is unusually, since the top-most currently running
4983 // activity should never have a canned thumbnail! Oh well.
4984 try {
4985 receiver.finished();
4986 } catch (RemoteException ex) {
4987 }
4988 }
4989
4990 return list;
4991 }
4992
4993 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
4994 int flags) {
4995 synchronized (this) {
4996 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
4997 "getRecentTasks()");
4998
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004999 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005001 final int N = mRecentTasks.size();
5002 ArrayList<ActivityManager.RecentTaskInfo> res
5003 = new ArrayList<ActivityManager.RecentTaskInfo>(
5004 maxNum < N ? maxNum : N);
5005 for (int i=0; i<N && maxNum > 0; i++) {
5006 TaskRecord tr = mRecentTasks.get(i);
5007 if (((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
5008 || (tr.intent == null)
5009 || ((tr.intent.getFlags()
5010 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5011 ActivityManager.RecentTaskInfo rti
5012 = new ActivityManager.RecentTaskInfo();
5013 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005014 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005015 rti.baseIntent = new Intent(
5016 tr.intent != null ? tr.intent : tr.affinityIntent);
5017 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005018 rti.description = tr.lastDescription;
5019
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005020 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5021 // Check whether this activity is currently available.
5022 try {
5023 if (rti.origActivity != null) {
5024 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5025 continue;
5026 }
5027 } else if (rti.baseIntent != null) {
5028 if (pm.queryIntentActivities(rti.baseIntent,
5029 null, 0) == null) {
5030 continue;
5031 }
5032 }
5033 } catch (RemoteException e) {
5034 // Will never happen.
5035 }
5036 }
5037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005038 res.add(rti);
5039 maxNum--;
5040 }
5041 }
5042 return res;
5043 }
5044 }
5045
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005046 private TaskRecord taskForIdLocked(int id) {
5047 final int N = mRecentTasks.size();
5048 for (int i=0; i<N; i++) {
5049 TaskRecord tr = mRecentTasks.get(i);
5050 if (tr.taskId == id) {
5051 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005052 }
5053 }
5054 return null;
5055 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005056
5057 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5058 synchronized (this) {
5059 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5060 "getTaskThumbnails()");
5061 TaskRecord tr = taskForIdLocked(id);
5062 if (tr != null) {
5063 return mMainStack.getTaskThumbnailsLocked(tr);
5064 }
5065 }
5066 return null;
5067 }
5068
5069 public boolean removeSubTask(int taskId, int subTaskIndex) {
5070 synchronized (this) {
5071 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5072 "removeSubTask()");
5073 long ident = Binder.clearCallingIdentity();
5074 try {
5075 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5076 } finally {
5077 Binder.restoreCallingIdentity(ident);
5078 }
5079 }
5080 }
5081
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005082 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005083 TaskRecord tr = root.task;
5084 Intent baseIntent = new Intent(
5085 tr.intent != null ? tr.intent : tr.affinityIntent);
5086 ComponentName component = baseIntent.getComponent();
5087 if (component == null) {
5088 Slog.w(TAG, "Now component for base intent of task: " + tr);
5089 return;
5090 }
5091
5092 // Find any running services associated with this app.
5093 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5094 for (ServiceRecord sr : mServices.values()) {
5095 if (sr.packageName.equals(component.getPackageName())) {
5096 services.add(sr);
5097 }
5098 }
5099
5100 // Take care of any running services associated with the app.
5101 for (int i=0; i<services.size(); i++) {
5102 ServiceRecord sr = services.get(i);
5103 if (sr.startRequested) {
5104 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005105 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005106 stopServiceLocked(sr);
5107 } else {
5108 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5109 sr.makeNextStartId(), baseIntent, -1));
5110 if (sr.app != null && sr.app.thread != null) {
5111 sendServiceArgsLocked(sr, false);
5112 }
5113 }
5114 }
5115 }
5116
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005117 if (killProcesses) {
5118 // Find any running processes associated with this app.
5119 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5120 SparseArray<ProcessRecord> appProcs
5121 = mProcessNames.getMap().get(component.getPackageName());
5122 if (appProcs != null) {
5123 for (int i=0; i<appProcs.size(); i++) {
5124 procs.add(appProcs.valueAt(i));
5125 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005126 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005127
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005128 // Kill the running processes.
5129 for (int i=0; i<procs.size(); i++) {
5130 ProcessRecord pr = procs.get(i);
5131 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5132 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5133 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5134 pr.processName, pr.setAdj, "remove task");
5135 Process.killProcessQuiet(pr.pid);
5136 } else {
5137 pr.waitingToKill = "remove task";
5138 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005139 }
5140 }
5141 }
5142
5143 public boolean removeTask(int taskId, int flags) {
5144 synchronized (this) {
5145 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5146 "removeTask()");
5147 long ident = Binder.clearCallingIdentity();
5148 try {
5149 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5150 if (r != null) {
5151 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005152 cleanUpRemovedTaskLocked(r,
5153 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005154 return true;
5155 }
5156 } finally {
5157 Binder.restoreCallingIdentity(ident);
5158 }
5159 }
5160 return false;
5161 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005163 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5164 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005165 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005166 TaskRecord jt = startTask;
5167
5168 // First look backwards
5169 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005170 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005171 if (r.task != jt) {
5172 jt = r.task;
5173 if (affinity.equals(jt.affinity)) {
5174 return j;
5175 }
5176 }
5177 }
5178
5179 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005180 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005181 jt = startTask;
5182 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005183 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005184 if (r.task != jt) {
5185 if (affinity.equals(jt.affinity)) {
5186 return j;
5187 }
5188 jt = r.task;
5189 }
5190 }
5191
5192 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005193 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005194 return N-1;
5195 }
5196
5197 return -1;
5198 }
5199
5200 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005201 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005202 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005203 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5205 "moveTaskToFront()");
5206
5207 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005208 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5209 Binder.getCallingUid(), "Task to front")) {
5210 return;
5211 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005212 final long origId = Binder.clearCallingIdentity();
5213 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005214 TaskRecord tr = taskForIdLocked(task);
5215 if (tr != null) {
5216 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5217 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005219 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5220 // Caller wants the home activity moved with it. To accomplish this,
5221 // we'll just move the home task to the top first.
5222 mMainStack.moveHomeToFrontLocked();
5223 }
5224 mMainStack.moveTaskToFrontLocked(tr, null);
5225 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005227 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5228 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005229 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005230 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5231 mMainStack.mUserLeaving = true;
5232 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005233 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5234 // Caller wants the home activity moved with it. To accomplish this,
5235 // we'll just move the home task to the top first.
5236 mMainStack.moveHomeToFrontLocked();
5237 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005238 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005239 return;
5240 }
5241 }
5242 } finally {
5243 Binder.restoreCallingIdentity(origId);
5244 }
5245 }
5246 }
5247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005248 public void moveTaskToBack(int task) {
5249 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5250 "moveTaskToBack()");
5251
5252 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005253 if (mMainStack.mResumedActivity != null
5254 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005255 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5256 Binder.getCallingUid(), "Task to back")) {
5257 return;
5258 }
5259 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005260 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005261 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005262 Binder.restoreCallingIdentity(origId);
5263 }
5264 }
5265
5266 /**
5267 * Moves an activity, and all of the other activities within the same task, to the bottom
5268 * of the history stack. The activity's order within the task is unchanged.
5269 *
5270 * @param token A reference to the activity we wish to move
5271 * @param nonRoot If false then this only works if the activity is the root
5272 * of a task; if true it will work for any activity in a task.
5273 * @return Returns true if the move completed, false if not.
5274 */
5275 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5276 synchronized(this) {
5277 final long origId = Binder.clearCallingIdentity();
5278 int taskId = getTaskForActivityLocked(token, !nonRoot);
5279 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005280 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005281 }
5282 Binder.restoreCallingIdentity(origId);
5283 }
5284 return false;
5285 }
5286
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005287 public void moveTaskBackwards(int task) {
5288 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5289 "moveTaskBackwards()");
5290
5291 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005292 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5293 Binder.getCallingUid(), "Task backwards")) {
5294 return;
5295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005296 final long origId = Binder.clearCallingIdentity();
5297 moveTaskBackwardsLocked(task);
5298 Binder.restoreCallingIdentity(origId);
5299 }
5300 }
5301
5302 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005303 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005304 }
5305
5306 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5307 synchronized(this) {
5308 return getTaskForActivityLocked(token, onlyRoot);
5309 }
5310 }
5311
5312 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005313 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005314 TaskRecord lastTask = null;
5315 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005316 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 if (r == token) {
5318 if (!onlyRoot || lastTask != r.task) {
5319 return r.task.taskId;
5320 }
5321 return -1;
5322 }
5323 lastTask = r.task;
5324 }
5325
5326 return -1;
5327 }
5328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005329 public void finishOtherInstances(IBinder token, ComponentName className) {
5330 synchronized(this) {
5331 final long origId = Binder.clearCallingIdentity();
5332
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005333 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005334 TaskRecord lastTask = null;
5335 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005336 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 if (r.realActivity.equals(className)
5338 && r != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005339 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005340 null, "others")) {
5341 i--;
5342 N--;
5343 }
5344 }
5345 lastTask = r.task;
5346 }
5347
5348 Binder.restoreCallingIdentity(origId);
5349 }
5350 }
5351
5352 // =========================================================
5353 // THUMBNAILS
5354 // =========================================================
5355
5356 public void reportThumbnail(IBinder token,
5357 Bitmap thumbnail, CharSequence description) {
5358 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5359 final long origId = Binder.clearCallingIdentity();
5360 sendPendingThumbnail(null, token, thumbnail, description, true);
5361 Binder.restoreCallingIdentity(origId);
5362 }
5363
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005364 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005365 Bitmap thumbnail, CharSequence description, boolean always) {
5366 TaskRecord task = null;
5367 ArrayList receivers = null;
5368
5369 //System.out.println("Send pending thumbnail: " + r);
5370
5371 synchronized(this) {
5372 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005373 r = mMainStack.isInStackLocked(token);
5374 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005375 return;
5376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005377 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005378 if (thumbnail == null && r.thumbHolder != null) {
5379 thumbnail = r.thumbHolder.lastThumbnail;
5380 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 }
5382 if (thumbnail == null && !always) {
5383 // If there is no thumbnail, and this entry is not actually
5384 // going away, then abort for now and pick up the next
5385 // thumbnail we get.
5386 return;
5387 }
5388 task = r.task;
5389
5390 int N = mPendingThumbnails.size();
5391 int i=0;
5392 while (i<N) {
5393 PendingThumbnailsRecord pr =
5394 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5395 //System.out.println("Looking in " + pr.pendingRecords);
5396 if (pr.pendingRecords.remove(r)) {
5397 if (receivers == null) {
5398 receivers = new ArrayList();
5399 }
5400 receivers.add(pr);
5401 if (pr.pendingRecords.size() == 0) {
5402 pr.finished = true;
5403 mPendingThumbnails.remove(i);
5404 N--;
5405 continue;
5406 }
5407 }
5408 i++;
5409 }
5410 }
5411
5412 if (receivers != null) {
5413 final int N = receivers.size();
5414 for (int i=0; i<N; i++) {
5415 try {
5416 PendingThumbnailsRecord pr =
5417 (PendingThumbnailsRecord)receivers.get(i);
5418 pr.receiver.newThumbnail(
5419 task != null ? task.taskId : -1, thumbnail, description);
5420 if (pr.finished) {
5421 pr.receiver.finished();
5422 }
5423 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005424 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 }
5426 }
5427 }
5428 }
5429
5430 // =========================================================
5431 // CONTENT PROVIDERS
5432 // =========================================================
5433
Jeff Brown10e89712011-07-08 18:52:57 -07005434 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5435 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005437 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005438 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005439 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005440 } catch (RemoteException ex) {
5441 }
5442 if (providers != null) {
5443 final int N = providers.size();
5444 for (int i=0; i<N; i++) {
5445 ProviderInfo cpi =
5446 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005447 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5448 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005449 if (cpr == null) {
5450 cpr = new ContentProviderRecord(cpi, app.info);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005451 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005452 }
5453 app.pubProviders.put(cpi.name, cpr);
5454 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005455 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 }
5457 }
5458 return providers;
5459 }
5460
5461 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005462 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5464 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5465 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005466 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005467 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005468 return null;
5469 }
5470 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005471 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005472 == PackageManager.PERMISSION_GRANTED) {
5473 return null;
5474 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005475
5476 PathPermission[] pps = cpi.pathPermissions;
5477 if (pps != null) {
5478 int i = pps.length;
5479 while (i > 0) {
5480 i--;
5481 PathPermission pp = pps[i];
5482 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005483 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005484 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005485 return null;
5486 }
5487 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005488 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005489 == PackageManager.PERMISSION_GRANTED) {
5490 return null;
5491 }
5492 }
5493 }
5494
Dianne Hackbornb424b632010-08-18 15:59:05 -07005495 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5496 if (perms != null) {
5497 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5498 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5499 return null;
5500 }
5501 }
5502 }
5503
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005504 String msg;
5505 if (!cpi.exported) {
5506 msg = "Permission Denial: opening provider " + cpi.name
5507 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5508 + ", uid=" + callingUid + ") that is not exported from uid "
5509 + cpi.applicationInfo.uid;
5510 } else {
5511 msg = "Permission Denial: opening provider " + cpi.name
5512 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5513 + ", uid=" + callingUid + ") requires "
5514 + cpi.readPermission + " or " + cpi.writePermission;
5515 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005516 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005517 return msg;
5518 }
5519
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005520 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5521 if (r != null) {
5522 Integer cnt = r.conProviders.get(cpr);
5523 if (DEBUG_PROVIDER) Slog.v(TAG,
5524 "Adding provider requested by "
5525 + r.processName + " from process "
5526 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5527 + " cnt=" + (cnt == null ? 1 : cnt));
5528 if (cnt == null) {
5529 cpr.clients.add(r);
5530 r.conProviders.put(cpr, new Integer(1));
5531 return true;
5532 } else {
5533 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5534 }
5535 } else {
5536 cpr.externals++;
5537 }
5538 return false;
5539 }
5540
5541 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5542 if (r != null) {
5543 Integer cnt = r.conProviders.get(cpr);
5544 if (DEBUG_PROVIDER) Slog.v(TAG,
5545 "Removing provider requested by "
5546 + r.processName + " from process "
5547 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5548 + " cnt=" + cnt);
5549 if (cnt == null || cnt.intValue() <= 1) {
5550 cpr.clients.remove(r);
5551 r.conProviders.remove(cpr);
5552 return true;
5553 } else {
5554 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5555 }
5556 } else {
5557 cpr.externals++;
5558 }
5559 return false;
5560 }
5561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005562 private final ContentProviderHolder getContentProviderImpl(
5563 IApplicationThread caller, String name) {
5564 ContentProviderRecord cpr;
5565 ProviderInfo cpi = null;
5566
5567 synchronized(this) {
5568 ProcessRecord r = null;
5569 if (caller != null) {
5570 r = getRecordForAppLocked(caller);
5571 if (r == null) {
5572 throw new SecurityException(
5573 "Unable to find app for caller " + caller
5574 + " (pid=" + Binder.getCallingPid()
5575 + ") when getting content provider " + name);
5576 }
5577 }
5578
5579 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005580 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005581 boolean providerRunning = cpr != null;
5582 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005583 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005584 String msg;
5585 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5586 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005587 }
5588
5589 if (r != null && cpr.canRunHere(r)) {
5590 // This provider has been published or is in the process
5591 // of being published... but it is also allowed to run
5592 // in the caller's process, so don't make a connection
5593 // and just let the caller instantiate its own instance.
5594 if (cpr.provider != null) {
5595 // don't give caller the provider object, it needs
5596 // to make its own.
5597 cpr = new ContentProviderRecord(cpr);
5598 }
5599 return cpr;
5600 }
5601
5602 final long origId = Binder.clearCallingIdentity();
5603
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005604 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005605 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005606 final boolean countChanged = incProviderCount(r, cpr);
5607 if (countChanged) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005608 if (cpr.app != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005609 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005610 // make sure to count it as being accessed and thus
5611 // back up on the LRU list. This is good because
5612 // content providers are often expensive to start.
5613 updateLruProcessLocked(cpr.app, false, true);
5614 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005615 }
5616
5617 if (cpr.app != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005618 if (false) {
5619 if (cpr.name.flattenToShortString().equals(
5620 "com.android.providers.calendar/.CalendarProvider2")) {
5621 Slog.v(TAG, "****************** KILLING "
5622 + cpr.name.flattenToShortString());
5623 Process.killProcess(cpr.app.pid);
5624 }
5625 }
5626 boolean success = updateOomAdjLocked(cpr.app);
5627 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5628 // NOTE: there is still a race here where a signal could be
5629 // pending on the process even though we managed to update its
5630 // adj level. Not sure what to do about this, but at least
5631 // the race is now smaller.
5632 if (!success) {
5633 // Uh oh... it looks like the provider's process
5634 // has been killed on us. We need to wait for a new
5635 // process to be started, and make sure its death
5636 // doesn't kill our process.
5637 Slog.i(TAG,
5638 "Existing provider " + cpr.name.flattenToShortString()
5639 + " is crashing; detaching " + r);
5640 boolean lastRef = decProviderCount(r, cpr);
5641 appDiedLocked(cpr.app, cpr.app.pid, cpr.app.thread);
5642 if (!lastRef) {
5643 // This wasn't the last ref our process had on
5644 // the provider... we have now been killed, bail.
5645 return null;
5646 }
5647 providerRunning = false;
5648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005649 }
5650
5651 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005652 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005653
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005654 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005655 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005656 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005657 resolveContentProvider(name,
5658 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005659 } catch (RemoteException ex) {
5660 }
5661 if (cpi == null) {
5662 return null;
5663 }
5664
Dianne Hackbornb424b632010-08-18 15:59:05 -07005665 String msg;
5666 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5667 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005668 }
5669
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005670 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005671 && !cpi.processName.equals("system")) {
5672 // If this content provider does not run in the system
5673 // process, and the system is not yet ready to run other
5674 // processes, then fail fast instead of hanging.
5675 throw new IllegalArgumentException(
5676 "Attempt to launch content provider before system ready");
5677 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005678
5679 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5680 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005681 final boolean firstClass = cpr == null;
5682 if (firstClass) {
5683 try {
5684 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005685 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005686 getApplicationInfo(
5687 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005688 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005690 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005691 + cpi.name);
5692 return null;
5693 }
5694 cpr = new ContentProviderRecord(cpi, ai);
5695 } catch (RemoteException ex) {
5696 // pm is in same process, this will never happen.
5697 }
5698 }
5699
5700 if (r != null && cpr.canRunHere(r)) {
5701 // If this is a multiprocess provider, then just return its
5702 // info and allow the caller to instantiate it. Only do
5703 // this if the provider is the same user as the caller's
5704 // process, or can run as root (so can be in any process).
5705 return cpr;
5706 }
5707
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005708 if (DEBUG_PROVIDER) {
5709 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005710 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005711 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005712 }
5713
5714 // This is single process, and our app is now connecting to it.
5715 // See if we are already in the process of launching this
5716 // provider.
5717 final int N = mLaunchingProviders.size();
5718 int i;
5719 for (i=0; i<N; i++) {
5720 if (mLaunchingProviders.get(i) == cpr) {
5721 break;
5722 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005723 }
5724
5725 // If the provider is not already being launched, then get it
5726 // started.
5727 if (i >= N) {
5728 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005729
5730 try {
5731 // Content provider is now in use, its package can't be stopped.
5732 try {
5733 AppGlobals.getPackageManager().setPackageStoppedState(
5734 cpr.appInfo.packageName, false);
5735 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005736 } catch (IllegalArgumentException e) {
5737 Slog.w(TAG, "Failed trying to unstop package "
5738 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005739 }
5740
5741 ProcessRecord proc = startProcessLocked(cpi.processName,
5742 cpr.appInfo, false, 0, "content provider",
5743 new ComponentName(cpi.applicationInfo.packageName,
5744 cpi.name), false);
5745 if (proc == null) {
5746 Slog.w(TAG, "Unable to launch app "
5747 + cpi.applicationInfo.packageName + "/"
5748 + cpi.applicationInfo.uid + " for provider "
5749 + name + ": process is bad");
5750 return null;
5751 }
5752 cpr.launchingApp = proc;
5753 mLaunchingProviders.add(cpr);
5754 } finally {
5755 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005756 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005757 }
5758
5759 // Make sure the provider is published (the same provider class
5760 // may be published under multiple names).
5761 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005762 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 }
5764 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005765 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005766 }
5767 }
5768
5769 // Wait for the provider to be published...
5770 synchronized (cpr) {
5771 while (cpr.provider == null) {
5772 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005773 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005774 + cpi.applicationInfo.packageName + "/"
5775 + cpi.applicationInfo.uid + " for provider "
5776 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08005777 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005778 cpi.applicationInfo.packageName,
5779 cpi.applicationInfo.uid, name);
5780 return null;
5781 }
5782 try {
5783 cpr.wait();
5784 } catch (InterruptedException ex) {
5785 }
5786 }
5787 }
5788 return cpr;
5789 }
5790
5791 public final ContentProviderHolder getContentProvider(
5792 IApplicationThread caller, String name) {
5793 if (caller == null) {
5794 String msg = "null IApplicationThread when getting content provider "
5795 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005796 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005797 throw new SecurityException(msg);
5798 }
5799
5800 return getContentProviderImpl(caller, name);
5801 }
5802
5803 private ContentProviderHolder getContentProviderExternal(String name) {
5804 return getContentProviderImpl(null, name);
5805 }
5806
5807 /**
5808 * Drop a content provider from a ProcessRecord's bookkeeping
5809 * @param cpr
5810 */
5811 public void removeContentProvider(IApplicationThread caller, String name) {
5812 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005813 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005814 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005815 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005816 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005817 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005818 return;
5819 }
5820 final ProcessRecord r = getRecordForAppLocked(caller);
5821 if (r == null) {
5822 throw new SecurityException(
5823 "Unable to find app for caller " + caller +
5824 " when removing content provider " + name);
5825 }
5826 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005827 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5828 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005829 if (localCpr.app == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005830 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08005831 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005832 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005833 return;
5834 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005835 if (decProviderCount(r, localCpr)) {
5836 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07005837 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 }
5840 }
5841
5842 private void removeContentProviderExternal(String name) {
5843 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07005844 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005845 if(cpr == null) {
5846 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08005847 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005848 return;
5849 }
5850
5851 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005852 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
5853 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005854 localCpr.externals--;
5855 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005856 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005857 }
5858 updateOomAdjLocked();
5859 }
5860 }
5861
5862 public final void publishContentProviders(IApplicationThread caller,
5863 List<ContentProviderHolder> providers) {
5864 if (providers == null) {
5865 return;
5866 }
5867
5868 synchronized(this) {
5869 final ProcessRecord r = getRecordForAppLocked(caller);
5870 if (r == null) {
5871 throw new SecurityException(
5872 "Unable to find app for caller " + caller
5873 + " (pid=" + Binder.getCallingPid()
5874 + ") when publishing content providers");
5875 }
5876
5877 final long origId = Binder.clearCallingIdentity();
5878
5879 final int N = providers.size();
5880 for (int i=0; i<N; i++) {
5881 ContentProviderHolder src = providers.get(i);
5882 if (src == null || src.info == null || src.provider == null) {
5883 continue;
5884 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07005885 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005886 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005887 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
5888 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005889 String names[] = dst.info.authority.split(";");
5890 for (int j = 0; j < names.length; j++) {
5891 mProvidersByName.put(names[j], dst);
5892 }
5893
5894 int NL = mLaunchingProviders.size();
5895 int j;
5896 for (j=0; j<NL; j++) {
5897 if (mLaunchingProviders.get(j) == dst) {
5898 mLaunchingProviders.remove(j);
5899 j--;
5900 NL--;
5901 }
5902 }
5903 synchronized (dst) {
5904 dst.provider = src.provider;
5905 dst.app = r;
5906 dst.notifyAll();
5907 }
5908 updateOomAdjLocked(r);
5909 }
5910 }
5911
5912 Binder.restoreCallingIdentity(origId);
5913 }
5914 }
5915
5916 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07005917 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06005918 synchronized (mSelf) {
5919 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
5920 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08005921 if (providers != null) {
5922 for (int i=providers.size()-1; i>=0; i--) {
5923 ProviderInfo pi = (ProviderInfo)providers.get(i);
5924 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
5925 Slog.w(TAG, "Not installing system proc provider " + pi.name
5926 + ": not system .apk");
5927 providers.remove(i);
5928 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005929 }
5930 }
5931 }
Josh Bartel2ecce342010-02-25 10:55:48 -06005932 if (providers != null) {
5933 mSystemThread.installSystemProviders(providers);
5934 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08005935
5936 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01005937
5938 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 }
5940
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07005941 /**
5942 * Allows app to retrieve the MIME type of a URI without having permission
5943 * to access its content provider.
5944 *
5945 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
5946 *
5947 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
5948 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
5949 */
5950 public String getProviderMimeType(Uri uri) {
5951 final String name = uri.getAuthority();
5952 final long ident = Binder.clearCallingIdentity();
5953 ContentProviderHolder holder = null;
5954
5955 try {
5956 holder = getContentProviderExternal(name);
5957 if (holder != null) {
5958 return holder.provider.getType(uri);
5959 }
5960 } catch (RemoteException e) {
5961 Log.w(TAG, "Content provider dead retrieving " + uri, e);
5962 return null;
5963 } finally {
5964 if (holder != null) {
5965 removeContentProviderExternal(name);
5966 }
5967 Binder.restoreCallingIdentity(ident);
5968 }
5969
5970 return null;
5971 }
5972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005973 // =========================================================
5974 // GLOBAL MANAGEMENT
5975 // =========================================================
5976
5977 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
5978 ApplicationInfo info, String customProcess) {
5979 String proc = customProcess != null ? customProcess : info.processName;
5980 BatteryStatsImpl.Uid.Proc ps = null;
5981 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5982 synchronized (stats) {
5983 ps = stats.getProcessStatsLocked(info.uid, proc);
5984 }
5985 return new ProcessRecord(ps, thread, info, proc);
5986 }
5987
5988 final ProcessRecord addAppLocked(ApplicationInfo info) {
5989 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
5990
5991 if (app == null) {
5992 app = newProcessRecordLocked(null, info, null);
5993 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08005994 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005995 }
5996
Dianne Hackborne7f97212011-02-24 14:40:20 -08005997 // This package really, really can not be stopped.
5998 try {
5999 AppGlobals.getPackageManager().setPackageStoppedState(
6000 info.packageName, false);
6001 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006002 } catch (IllegalArgumentException e) {
6003 Slog.w(TAG, "Failed trying to unstop package "
6004 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006005 }
6006
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006007 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6008 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6009 app.persistent = true;
Dianne Hackborn7d608422011-08-07 16:24:18 -07006010 app.maxAdj = ProcessList.CORE_SERVER_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006011 }
6012 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6013 mPersistentStartingProcesses.add(app);
6014 startProcessLocked(app, "added application", app.processName);
6015 }
6016
6017 return app;
6018 }
6019
6020 public void unhandledBack() {
6021 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6022 "unhandledBack()");
6023
6024 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006025 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006026 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006027 TAG, "Performing unhandledBack(): stack size = " + count);
6028 if (count > 1) {
6029 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006030 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006031 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6032 Binder.restoreCallingIdentity(origId);
6033 }
6034 }
6035 }
6036
6037 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6038 String name = uri.getAuthority();
6039 ContentProviderHolder cph = getContentProviderExternal(name);
6040 ParcelFileDescriptor pfd = null;
6041 if (cph != null) {
6042 // We record the binder invoker's uid in thread-local storage before
6043 // going to the content provider to open the file. Later, in the code
6044 // that handles all permissions checks, we look for this uid and use
6045 // that rather than the Activity Manager's own uid. The effect is that
6046 // we do the check against the caller's permissions even though it looks
6047 // to the content provider like the Activity Manager itself is making
6048 // the request.
6049 sCallerIdentity.set(new Identity(
6050 Binder.getCallingPid(), Binder.getCallingUid()));
6051 try {
6052 pfd = cph.provider.openFile(uri, "r");
6053 } catch (FileNotFoundException e) {
6054 // do nothing; pfd will be returned null
6055 } finally {
6056 // Ensure that whatever happens, we clean up the identity state
6057 sCallerIdentity.remove();
6058 }
6059
6060 // We've got the fd now, so we're done with the provider.
6061 removeContentProviderExternal(name);
6062 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006063 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 }
6065 return pfd;
6066 }
6067
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006068 // Actually is sleeping or shutting down or whatever else in the future
6069 // is an inactive state.
6070 public boolean isSleeping() {
6071 return mSleeping || mShuttingDown;
6072 }
6073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 public void goingToSleep() {
6075 synchronized(this) {
6076 mSleeping = true;
6077 mWindowManager.setEventDispatching(false);
6078
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006079 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006080
6081 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006082 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006083 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6084 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006085 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 }
6087 }
6088
Dianne Hackborn55280a92009-05-07 15:53:46 -07006089 public boolean shutdown(int timeout) {
6090 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6091 != PackageManager.PERMISSION_GRANTED) {
6092 throw new SecurityException("Requires permission "
6093 + android.Manifest.permission.SHUTDOWN);
6094 }
6095
6096 boolean timedout = false;
6097
6098 synchronized(this) {
6099 mShuttingDown = true;
6100 mWindowManager.setEventDispatching(false);
6101
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006102 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006103 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006104 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006105 while (mMainStack.mResumedActivity != null
6106 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006107 long delay = endTime - System.currentTimeMillis();
6108 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006109 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006110 timedout = true;
6111 break;
6112 }
6113 try {
6114 this.wait();
6115 } catch (InterruptedException e) {
6116 }
6117 }
6118 }
6119 }
6120
6121 mUsageStatsService.shutdown();
6122 mBatteryStatsService.shutdown();
6123
6124 return timedout;
6125 }
6126
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006127 public final void activitySlept(IBinder token) {
6128 if (localLOGV) Slog.v(
6129 TAG, "Activity slept: token=" + token);
6130
6131 ActivityRecord r = null;
6132
6133 final long origId = Binder.clearCallingIdentity();
6134
6135 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006136 r = mMainStack.isInStackLocked(token);
6137 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006138 mMainStack.activitySleptLocked(r);
6139 }
6140 }
6141
6142 Binder.restoreCallingIdentity(origId);
6143 }
6144
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006145 public void wakingUp() {
6146 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006147 mWindowManager.setEventDispatching(true);
6148 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006149 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006150 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006151 }
6152 }
6153
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006154 public void stopAppSwitches() {
6155 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6156 != PackageManager.PERMISSION_GRANTED) {
6157 throw new SecurityException("Requires permission "
6158 + android.Manifest.permission.STOP_APP_SWITCHES);
6159 }
6160
6161 synchronized(this) {
6162 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6163 + APP_SWITCH_DELAY_TIME;
6164 mDidAppSwitch = false;
6165 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6166 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6167 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6168 }
6169 }
6170
6171 public void resumeAppSwitches() {
6172 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6173 != PackageManager.PERMISSION_GRANTED) {
6174 throw new SecurityException("Requires permission "
6175 + android.Manifest.permission.STOP_APP_SWITCHES);
6176 }
6177
6178 synchronized(this) {
6179 // Note that we don't execute any pending app switches... we will
6180 // let those wait until either the timeout, or the next start
6181 // activity request.
6182 mAppSwitchesAllowedTime = 0;
6183 }
6184 }
6185
6186 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6187 String name) {
6188 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6189 return true;
6190 }
6191
6192 final int perm = checkComponentPermission(
6193 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006194 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006195 if (perm == PackageManager.PERMISSION_GRANTED) {
6196 return true;
6197 }
6198
Joe Onorato8a9b2202010-02-26 18:56:32 -08006199 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006200 return false;
6201 }
6202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006203 public void setDebugApp(String packageName, boolean waitForDebugger,
6204 boolean persistent) {
6205 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6206 "setDebugApp()");
6207
6208 // Note that this is not really thread safe if there are multiple
6209 // callers into it at the same time, but that's not a situation we
6210 // care about.
6211 if (persistent) {
6212 final ContentResolver resolver = mContext.getContentResolver();
6213 Settings.System.putString(
6214 resolver, Settings.System.DEBUG_APP,
6215 packageName);
6216 Settings.System.putInt(
6217 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6218 waitForDebugger ? 1 : 0);
6219 }
6220
6221 synchronized (this) {
6222 if (!persistent) {
6223 mOrigDebugApp = mDebugApp;
6224 mOrigWaitForDebugger = mWaitForDebugger;
6225 }
6226 mDebugApp = packageName;
6227 mWaitForDebugger = waitForDebugger;
6228 mDebugTransient = !persistent;
6229 if (packageName != null) {
6230 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006231 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006232 Binder.restoreCallingIdentity(origId);
6233 }
6234 }
6235 }
6236
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006237 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6238 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6239 synchronized (this) {
6240 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6241 if (!isDebuggable) {
6242 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6243 throw new SecurityException("Process not debuggable: " + app.packageName);
6244 }
6245 }
6246 mProfileApp = processName;
6247 mProfileFile = profileFile;
6248 if (mProfileFd != null) {
6249 try {
6250 mProfileFd.close();
6251 } catch (IOException e) {
6252 }
6253 mProfileFd = null;
6254 }
6255 mProfileFd = profileFd;
6256 mProfileType = 0;
6257 mAutoStopProfiler = autoStopProfiler;
6258 }
6259 }
6260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006261 public void setAlwaysFinish(boolean enabled) {
6262 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6263 "setAlwaysFinish()");
6264
6265 Settings.System.putInt(
6266 mContext.getContentResolver(),
6267 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6268
6269 synchronized (this) {
6270 mAlwaysFinishActivities = enabled;
6271 }
6272 }
6273
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006274 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006275 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006276 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006278 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006279 }
6280 }
6281
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006282 public boolean isUserAMonkey() {
6283 // For now the fact that there is a controller implies
6284 // we have a monkey.
6285 synchronized (this) {
6286 return mController != null;
6287 }
6288 }
6289
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006290 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006291 synchronized (this) {
6292 mWatchers.register(watcher);
6293 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006294 }
6295
6296 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006297 synchronized (this) {
6298 mWatchers.unregister(watcher);
6299 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006300 }
6301
Jeff Sharkeya4620792011-05-20 15:29:23 -07006302 public void registerProcessObserver(IProcessObserver observer) {
6303 mProcessObservers.register(observer);
6304 }
6305
6306 public void unregisterProcessObserver(IProcessObserver observer) {
6307 mProcessObservers.unregister(observer);
6308 }
6309
Daniel Sandler69a48172010-06-23 16:29:36 -04006310 public void setImmersive(IBinder token, boolean immersive) {
6311 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006312 ActivityRecord r = mMainStack.isInStackLocked(token);
6313 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006314 throw new IllegalArgumentException();
6315 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006316 r.immersive = immersive;
6317 }
6318 }
6319
6320 public boolean isImmersive(IBinder token) {
6321 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006322 ActivityRecord r = mMainStack.isInStackLocked(token);
6323 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006324 throw new IllegalArgumentException();
6325 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006326 return r.immersive;
6327 }
6328 }
6329
6330 public boolean isTopActivityImmersive() {
6331 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006332 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006333 return (r != null) ? r.immersive : false;
6334 }
6335 }
6336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006337 public final void enterSafeMode() {
6338 synchronized(this) {
6339 // It only makes sense to do this before the system is ready
6340 // and started launching other packages.
6341 if (!mSystemReady) {
6342 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006343 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006344 } catch (RemoteException e) {
6345 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006346 }
6347 }
6348 }
6349
Jeff Brownb09abc12011-01-13 21:08:27 -08006350 public final void showSafeModeOverlay() {
6351 View v = LayoutInflater.from(mContext).inflate(
6352 com.android.internal.R.layout.safe_mode, null);
6353 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6354 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6355 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6356 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6357 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6358 lp.format = v.getBackground().getOpacity();
6359 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6360 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6361 ((WindowManager)mContext.getSystemService(
6362 Context.WINDOW_SERVICE)).addView(v, lp);
6363 }
6364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006365 public void noteWakeupAlarm(IIntentSender sender) {
6366 if (!(sender instanceof PendingIntentRecord)) {
6367 return;
6368 }
6369 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6370 synchronized (stats) {
6371 if (mBatteryStatsService.isOnBattery()) {
6372 mBatteryStatsService.enforceCallingPermission();
6373 PendingIntentRecord rec = (PendingIntentRecord)sender;
6374 int MY_UID = Binder.getCallingUid();
6375 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6376 BatteryStatsImpl.Uid.Pkg pkg =
6377 stats.getPackageStatsLocked(uid, rec.key.packageName);
6378 pkg.incWakeupsLocked();
6379 }
6380 }
6381 }
6382
Dianne Hackborn64825172011-03-02 21:32:58 -08006383 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006385 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006386 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006387 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006388 // XXX Note: don't acquire main activity lock here, because the window
6389 // manager calls in with its locks held.
6390
6391 boolean killed = false;
6392 synchronized (mPidsSelfLocked) {
6393 int[] types = new int[pids.length];
6394 int worstType = 0;
6395 for (int i=0; i<pids.length; i++) {
6396 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6397 if (proc != null) {
6398 int type = proc.setAdj;
6399 types[i] = type;
6400 if (type > worstType) {
6401 worstType = type;
6402 }
6403 }
6404 }
6405
Dianne Hackborn64825172011-03-02 21:32:58 -08006406 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 // then constrain it so we will kill all hidden procs.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006408 if (worstType < ProcessList.EMPTY_APP_ADJ && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
6409 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006410 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006411
6412 // If this is not a secure call, don't let it kill processes that
6413 // are important.
Dianne Hackborn7d608422011-08-07 16:24:18 -07006414 if (!secure && worstType < ProcessList.SECONDARY_SERVER_ADJ) {
6415 worstType = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006416 }
6417
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006418 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006419 for (int i=0; i<pids.length; i++) {
6420 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6421 if (proc == null) {
6422 continue;
6423 }
6424 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006425 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006426 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006427 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6428 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006429 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006430 proc.killedBackground = true;
6431 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 }
6433 }
6434 }
6435 return killed;
6436 }
6437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006438 public final void startRunning(String pkg, String cls, String action,
6439 String data) {
6440 synchronized(this) {
6441 if (mStartRunning) {
6442 return;
6443 }
6444 mStartRunning = true;
6445 mTopComponent = pkg != null && cls != null
6446 ? new ComponentName(pkg, cls) : null;
6447 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6448 mTopData = data;
6449 if (!mSystemReady) {
6450 return;
6451 }
6452 }
6453
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006454 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006455 }
6456
6457 private void retrieveSettings() {
6458 final ContentResolver resolver = mContext.getContentResolver();
6459 String debugApp = Settings.System.getString(
6460 resolver, Settings.System.DEBUG_APP);
6461 boolean waitForDebugger = Settings.System.getInt(
6462 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6463 boolean alwaysFinishActivities = Settings.System.getInt(
6464 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6465
6466 Configuration configuration = new Configuration();
6467 Settings.System.getConfiguration(resolver, configuration);
6468
6469 synchronized (this) {
6470 mDebugApp = mOrigDebugApp = debugApp;
6471 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6472 mAlwaysFinishActivities = alwaysFinishActivities;
6473 // This happens before any activities are started, so we can
6474 // change mConfiguration in-place.
6475 mConfiguration.updateFrom(configuration);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08006476 mConfigurationSeq = mConfiguration.seq = 1;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006477 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 }
6479 }
6480
6481 public boolean testIsSystemReady() {
6482 // no need to synchronize(this) just to read & return the value
6483 return mSystemReady;
6484 }
6485
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006486 private static File getCalledPreBootReceiversFile() {
6487 File dataDir = Environment.getDataDirectory();
6488 File systemDir = new File(dataDir, "system");
6489 File fname = new File(systemDir, "called_pre_boots.dat");
6490 return fname;
6491 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006492
6493 static final int LAST_DONE_VERSION = 10000;
6494
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006495 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6496 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6497 File file = getCalledPreBootReceiversFile();
6498 FileInputStream fis = null;
6499 try {
6500 fis = new FileInputStream(file);
6501 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006502 int fvers = dis.readInt();
6503 if (fvers == LAST_DONE_VERSION) {
6504 String vers = dis.readUTF();
6505 String codename = dis.readUTF();
6506 String build = dis.readUTF();
6507 if (android.os.Build.VERSION.RELEASE.equals(vers)
6508 && android.os.Build.VERSION.CODENAME.equals(codename)
6509 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6510 int num = dis.readInt();
6511 while (num > 0) {
6512 num--;
6513 String pkg = dis.readUTF();
6514 String cls = dis.readUTF();
6515 lastDoneReceivers.add(new ComponentName(pkg, cls));
6516 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006517 }
6518 }
6519 } catch (FileNotFoundException e) {
6520 } catch (IOException e) {
6521 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6522 } finally {
6523 if (fis != null) {
6524 try {
6525 fis.close();
6526 } catch (IOException e) {
6527 }
6528 }
6529 }
6530 return lastDoneReceivers;
6531 }
6532
6533 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6534 File file = getCalledPreBootReceiversFile();
6535 FileOutputStream fos = null;
6536 DataOutputStream dos = null;
6537 try {
6538 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6539 fos = new FileOutputStream(file);
6540 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006541 dos.writeInt(LAST_DONE_VERSION);
6542 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006543 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006544 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006545 dos.writeInt(list.size());
6546 for (int i=0; i<list.size(); i++) {
6547 dos.writeUTF(list.get(i).getPackageName());
6548 dos.writeUTF(list.get(i).getClassName());
6549 }
6550 } catch (IOException e) {
6551 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6552 file.delete();
6553 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006554 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006555 if (dos != null) {
6556 try {
6557 dos.close();
6558 } catch (IOException e) {
6559 // TODO Auto-generated catch block
6560 e.printStackTrace();
6561 }
6562 }
6563 }
6564 }
6565
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006566 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006567 synchronized(this) {
6568 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006569 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006570 return;
6571 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006572
6573 // Check to see if there are any update receivers to run.
6574 if (!mDidUpdate) {
6575 if (mWaitingUpdate) {
6576 return;
6577 }
6578 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6579 List<ResolveInfo> ris = null;
6580 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006581 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006582 intent, null, 0);
6583 } catch (RemoteException e) {
6584 }
6585 if (ris != null) {
6586 for (int i=ris.size()-1; i>=0; i--) {
6587 if ((ris.get(i).activityInfo.applicationInfo.flags
6588 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6589 ris.remove(i);
6590 }
6591 }
6592 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006593
6594 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6595
6596 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006597 for (int i=0; i<ris.size(); i++) {
6598 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006599 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6600 if (lastDoneReceivers.contains(comp)) {
6601 ris.remove(i);
6602 i--;
6603 }
6604 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006605
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006606 for (int i=0; i<ris.size(); i++) {
6607 ActivityInfo ai = ris.get(i).activityInfo;
6608 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6609 doneReceivers.add(comp);
6610 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006611 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006612 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006613 finisher = new IIntentReceiver.Stub() {
6614 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006615 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006616 boolean sticky) {
6617 // The raw IIntentReceiver interface is called
6618 // with the AM lock held, so redispatch to
6619 // execute our code without the lock.
6620 mHandler.post(new Runnable() {
6621 public void run() {
6622 synchronized (ActivityManagerService.this) {
6623 mDidUpdate = true;
6624 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006625 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006626 showBootMessage(mContext.getText(
6627 R.string.android_upgrading_complete),
6628 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006629 systemReady(goingCallback);
6630 }
6631 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006632 }
6633 };
6634 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006635 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006636 broadcastIntentLocked(null, null, intent, null, finisher,
6637 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006638 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006639 mWaitingUpdate = true;
6640 }
6641 }
6642 }
6643 if (mWaitingUpdate) {
6644 return;
6645 }
6646 mDidUpdate = true;
6647 }
6648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006649 mSystemReady = true;
6650 if (!mStartRunning) {
6651 return;
6652 }
6653 }
6654
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006655 ArrayList<ProcessRecord> procsToKill = null;
6656 synchronized(mPidsSelfLocked) {
6657 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6658 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6659 if (!isAllowedWhileBooting(proc.info)){
6660 if (procsToKill == null) {
6661 procsToKill = new ArrayList<ProcessRecord>();
6662 }
6663 procsToKill.add(proc);
6664 }
6665 }
6666 }
6667
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006668 synchronized(this) {
6669 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006670 for (int i=procsToKill.size()-1; i>=0; i--) {
6671 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006672 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006673 removeProcessLocked(proc, true, false);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006674 }
6675 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006676
6677 // Now that we have cleaned up any update processes, we
6678 // are ready to start launching real processes and know that
6679 // we won't trample on them any more.
6680 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006681 }
6682
Joe Onorato8a9b2202010-02-26 18:56:32 -08006683 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006684 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006685 SystemClock.uptimeMillis());
6686
6687 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006688 // Make sure we have no pre-ready processes sitting around.
6689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006690 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6691 ResolveInfo ri = mContext.getPackageManager()
6692 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006693 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 CharSequence errorMsg = null;
6695 if (ri != null) {
6696 ActivityInfo ai = ri.activityInfo;
6697 ApplicationInfo app = ai.applicationInfo;
6698 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6699 mTopAction = Intent.ACTION_FACTORY_TEST;
6700 mTopData = null;
6701 mTopComponent = new ComponentName(app.packageName,
6702 ai.name);
6703 } else {
6704 errorMsg = mContext.getResources().getText(
6705 com.android.internal.R.string.factorytest_not_system);
6706 }
6707 } else {
6708 errorMsg = mContext.getResources().getText(
6709 com.android.internal.R.string.factorytest_no_action);
6710 }
6711 if (errorMsg != null) {
6712 mTopAction = null;
6713 mTopData = null;
6714 mTopComponent = null;
6715 Message msg = Message.obtain();
6716 msg.what = SHOW_FACTORY_ERROR_MSG;
6717 msg.getData().putCharSequence("msg", errorMsg);
6718 mHandler.sendMessage(msg);
6719 }
6720 }
6721 }
6722
6723 retrieveSettings();
6724
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006725 if (goingCallback != null) goingCallback.run();
6726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006727 synchronized (this) {
6728 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6729 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006730 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006731 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 if (apps != null) {
6733 int N = apps.size();
6734 int i;
6735 for (i=0; i<N; i++) {
6736 ApplicationInfo info
6737 = (ApplicationInfo)apps.get(i);
6738 if (info != null &&
6739 !info.packageName.equals("android")) {
6740 addAppLocked(info);
6741 }
6742 }
6743 }
6744 } catch (RemoteException ex) {
6745 // pm is in same process, this will never happen.
6746 }
6747 }
6748
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006749 // Start up initial activity.
6750 mBooting = true;
6751
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006752 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006753 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 Message msg = Message.obtain();
6755 msg.what = SHOW_UID_ERROR_MSG;
6756 mHandler.sendMessage(msg);
6757 }
6758 } catch (RemoteException e) {
6759 }
6760
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006761 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006762 }
6763 }
6764
Dan Egnorb7f03672009-12-09 16:22:32 -08006765 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006766 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006767 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006768 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006769 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006770 startAppProblemLocked(app);
6771 app.stopFreezingAllLocked();
6772 return handleAppCrashLocked(app);
6773 }
6774
Dan Egnorb7f03672009-12-09 16:22:32 -08006775 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006776 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006777 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08006778 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08006779 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
6780 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006781 startAppProblemLocked(app);
6782 app.stopFreezingAllLocked();
6783 }
6784
6785 /**
6786 * Generate a process error record, suitable for attachment to a ProcessRecord.
6787 *
6788 * @param app The ProcessRecord in which the error occurred.
6789 * @param condition Crashing, Application Not Responding, etc. Values are defined in
6790 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08006791 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006792 * @param shortMsg Short message describing the crash.
6793 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08006794 * @param stackTrace Full crash stack trace, may be null.
6795 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006796 * @return Returns a fully-formed AppErrorStateInfo record.
6797 */
6798 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08006799 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006800 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08006801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802 report.condition = condition;
6803 report.processName = app.processName;
6804 report.pid = app.pid;
6805 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08006806 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006807 report.shortMsg = shortMsg;
6808 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08006809 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810
6811 return report;
6812 }
6813
Dan Egnor42471dd2010-01-07 17:25:22 -08006814 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006815 synchronized (this) {
6816 app.crashing = false;
6817 app.crashingReport = null;
6818 app.notResponding = false;
6819 app.notRespondingReport = null;
6820 if (app.anrDialog == fromDialog) {
6821 app.anrDialog = null;
6822 }
6823 if (app.waitDialog == fromDialog) {
6824 app.waitDialog = null;
6825 }
6826 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08006827 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006828 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07006829 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
6830 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006831 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006833 }
6834 }
Dan Egnor42471dd2010-01-07 17:25:22 -08006835
Dan Egnorb7f03672009-12-09 16:22:32 -08006836 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006837 long now = SystemClock.uptimeMillis();
6838
6839 Long crashTime = mProcessCrashTimes.get(app.info.processName,
6840 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07006841 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006842 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08006843 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006844 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006845 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006846 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006847 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6848 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006849 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006850 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006851 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006852 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006853 }
6854 }
6855 if (!app.persistent) {
6856 // We don't want to start this process again until the user
6857 // explicitly does so... but for persistent process, we really
6858 // need to keep it running. If a persistent process is actually
6859 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08006860 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006861 app.info.processName);
6862 mBadProcesses.put(app.info.processName, app.info.uid, now);
6863 app.bad = true;
6864 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
6865 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07006866 // Don't let services in this process be restarted and potentially
6867 // annoy the user repeatedly. Unless it is persistent, since those
6868 // processes run critical code.
6869 removeProcessLocked(app, false, false);
Dianne Hackborncb44d962011-03-10 17:02:27 -08006870 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006871 return false;
6872 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08006873 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006874 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006875 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006876 if (r.app == app) {
6877 // If the top running activity is from this crashing
6878 // process, then terminate it to avoid getting in a loop.
6879 Slog.w(TAG, " Force finishing activity "
6880 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006881 int index = mMainStack.indexOfTokenLocked(r);
6882 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006883 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08006884 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006885 // stopped, to avoid a situation where one will get
6886 // re-start our crashing activity once it gets resumed again.
6887 index--;
6888 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006889 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006890 if (r.state == ActivityState.RESUMED
6891 || r.state == ActivityState.PAUSING
6892 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08006893 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006894 Slog.w(TAG, " Force finishing activity "
6895 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006896 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07006897 Activity.RESULT_CANCELED, null, "crashed");
6898 }
6899 }
6900 }
6901 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006902 }
6903
6904 // Bump up the crash count of any services currently running in the proc.
6905 if (app.services.size() != 0) {
6906 // Any services running in the application need to be placed
6907 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07006908 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006909 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006910 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006911 sr.crashCount++;
6912 }
6913 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02006914
6915 // If the crashing process is what we consider to be the "home process" and it has been
6916 // replaced by a third-party app, clear the package preferred activities from packages
6917 // with a home activity running in the process to prevent a repeatedly crashing app
6918 // from blocking the user to manually clear the list.
6919 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
6920 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
6921 Iterator it = mHomeProcess.activities.iterator();
6922 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07006923 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02006924 if (r.isHomeActivity) {
6925 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
6926 try {
6927 ActivityThread.getPackageManager()
6928 .clearPackagePreferredActivities(r.packageName);
6929 } catch (RemoteException c) {
6930 // pm is in same process, this will never happen.
6931 }
6932 }
6933 }
6934 }
6935
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006936 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
6937 return true;
6938 }
6939
6940 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08006941 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
6942 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006943 skipCurrentReceiverLocked(app);
6944 }
6945
6946 void skipCurrentReceiverLocked(ProcessRecord app) {
6947 boolean reschedule = false;
6948 BroadcastRecord r = app.curReceiver;
6949 if (r != null) {
6950 // The current broadcast is waiting for this app's receiver
6951 // to be finished. Looks like that's not going to happen, so
6952 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07006953 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006954 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6955 r.resultExtras, r.resultAbort, true);
6956 reschedule = true;
6957 }
6958 r = mPendingBroadcast;
6959 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006960 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006961 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07006962 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006963 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
6964 r.resultExtras, r.resultAbort, true);
6965 reschedule = true;
6966 }
6967 if (reschedule) {
6968 scheduleBroadcastsLocked();
6969 }
6970 }
6971
Dan Egnor60d87622009-12-16 16:32:58 -08006972 /**
6973 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
6974 * The application process will exit immediately after this call returns.
6975 * @param app object of the crashing app, null for the system server
6976 * @param crashInfo describing the exception
6977 */
6978 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006979 ProcessRecord r = findAppProcess(app, "Crash");
Dan Egnor60d87622009-12-16 16:32:58 -08006980
6981 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
6982 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08006983 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08006984 crashInfo.exceptionClassName,
6985 crashInfo.exceptionMessage,
6986 crashInfo.throwFileName,
6987 crashInfo.throwLineNumber);
6988
Dan Egnor42471dd2010-01-07 17:25:22 -08006989 addErrorToDropBox("crash", r, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08006990
6991 crashApplication(r, crashInfo);
6992 }
6993
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07006994 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07006995 IBinder app,
6996 int violationMask,
6997 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08006998 ProcessRecord r = findAppProcess(app, "StrictMode");
6999 if (r == null) {
7000 return;
7001 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007002
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007003 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007004 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007005 boolean logIt = true;
7006 synchronized (mAlreadyLoggedViolatedStacks) {
7007 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7008 logIt = false;
7009 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007010 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007011 // the relative pain numbers, without logging all
7012 // the stack traces repeatedly. We'd want to do
7013 // likewise in the client code, which also does
7014 // dup suppression, before the Binder call.
7015 } else {
7016 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7017 mAlreadyLoggedViolatedStacks.clear();
7018 }
7019 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7020 }
7021 }
7022 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007023 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007024 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007025 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007026
7027 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7028 AppErrorResult result = new AppErrorResult();
7029 synchronized (this) {
7030 final long origId = Binder.clearCallingIdentity();
7031
7032 Message msg = Message.obtain();
7033 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7034 HashMap<String, Object> data = new HashMap<String, Object>();
7035 data.put("result", result);
7036 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007037 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007038 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007039 msg.obj = data;
7040 mHandler.sendMessage(msg);
7041
7042 Binder.restoreCallingIdentity(origId);
7043 }
7044 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007045 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007046 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007047 }
7048
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007049 // Depending on the policy in effect, there could be a bunch of
7050 // these in quick succession so we try to batch these together to
7051 // minimize disk writes, number of dropbox entries, and maximize
7052 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007053 private void logStrictModeViolationToDropBox(
7054 ProcessRecord process,
7055 StrictMode.ViolationInfo info) {
7056 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007057 return;
7058 }
7059 final boolean isSystemApp = process == null ||
7060 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7061 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
7062 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7063 final DropBoxManager dbox = (DropBoxManager)
7064 mContext.getSystemService(Context.DROPBOX_SERVICE);
7065
7066 // Exit early if the dropbox isn't configured to accept this report type.
7067 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7068
7069 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007070 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007071 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7072 synchronized (sb) {
7073 bufferWasEmpty = sb.length() == 0;
7074 appendDropBoxProcessHeaders(process, sb);
7075 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7076 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007077 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7078 if (info.violationNumThisLoop != 0) {
7079 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7080 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007081 if (info.numAnimationsRunning != 0) {
7082 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7083 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007084 if (info.broadcastIntentAction != null) {
7085 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7086 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007087 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007088 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007089 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007090 if (info.numInstances != -1) {
7091 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7092 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007093 if (info.tags != null) {
7094 for (String tag : info.tags) {
7095 sb.append("Span-Tag: ").append(tag).append("\n");
7096 }
7097 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007098 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007099 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7100 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007101 }
7102 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007103
7104 // Only buffer up to ~64k. Various logging bits truncate
7105 // things at 128k.
7106 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007107 }
7108
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007109 // Flush immediately if the buffer's grown too large, or this
7110 // is a non-system app. Non-system apps are isolated with a
7111 // different tag & policy and not batched.
7112 //
7113 // Batching is useful during internal testing with
7114 // StrictMode settings turned up high. Without batching,
7115 // thousands of separate files could be created on boot.
7116 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007117 new Thread("Error dump: " + dropboxTag) {
7118 @Override
7119 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007120 String report;
7121 synchronized (sb) {
7122 report = sb.toString();
7123 sb.delete(0, sb.length());
7124 sb.trimToSize();
7125 }
7126 if (report.length() != 0) {
7127 dbox.addText(dropboxTag, report);
7128 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007129 }
7130 }.start();
7131 return;
7132 }
7133
7134 // System app batching:
7135 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007136 // An existing dropbox-writing thread is outstanding, so
7137 // we don't need to start it up. The existing thread will
7138 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007139 return;
7140 }
7141
7142 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7143 // (After this point, we shouldn't access AMS internal data structures.)
7144 new Thread("Error dump: " + dropboxTag) {
7145 @Override
7146 public void run() {
7147 // 5 second sleep to let stacks arrive and be batched together
7148 try {
7149 Thread.sleep(5000); // 5 seconds
7150 } catch (InterruptedException e) {}
7151
7152 String errorReport;
7153 synchronized (mStrictModeBuffer) {
7154 errorReport = mStrictModeBuffer.toString();
7155 if (errorReport.length() == 0) {
7156 return;
7157 }
7158 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7159 mStrictModeBuffer.trimToSize();
7160 }
7161 dbox.addText(dropboxTag, errorReport);
7162 }
7163 }.start();
7164 }
7165
Dan Egnor60d87622009-12-16 16:32:58 -08007166 /**
7167 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7168 * @param app object of the crashing app, null for the system server
7169 * @param tag reported by the caller
7170 * @param crashInfo describing the context of the error
7171 * @return true if the process should exit immediately (WTF is fatal)
7172 */
7173 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007174 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007175 ProcessRecord r = findAppProcess(app, "WTF");
Dan Egnor60d87622009-12-16 16:32:58 -08007176
7177 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
7178 app == null ? "system" : (r == null ? "unknown" : r.processName),
Dan Egnor2780e732010-01-22 14:47:35 -08007179 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007180 tag, crashInfo.exceptionMessage);
7181
Dan Egnor42471dd2010-01-07 17:25:22 -08007182 addErrorToDropBox("wtf", r, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007183
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007184 if (r != null && r.pid != Process.myPid() &&
7185 Settings.Secure.getInt(mContext.getContentResolver(),
7186 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007187 crashApplication(r, crashInfo);
7188 return true;
7189 } else {
7190 return false;
7191 }
7192 }
7193
7194 /**
7195 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7196 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7197 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007198 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007199 if (app == null) {
7200 return null;
7201 }
7202
7203 synchronized (this) {
7204 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7205 final int NA = apps.size();
7206 for (int ia=0; ia<NA; ia++) {
7207 ProcessRecord p = apps.valueAt(ia);
7208 if (p.thread != null && p.thread.asBinder() == app) {
7209 return p;
7210 }
7211 }
7212 }
7213
Dianne Hackborncb44d962011-03-10 17:02:27 -08007214 Slog.w(TAG, "Can't find mystery application for " + reason
7215 + " from pid=" + Binder.getCallingPid()
7216 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007217 return null;
7218 }
7219 }
7220
7221 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007222 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7223 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007224 */
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007225 private void appendDropBoxProcessHeaders(ProcessRecord process, StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007226 // Watchdog thread ends up invoking this function (with
7227 // a null ProcessRecord) to add the stack file to dropbox.
7228 // Do not acquire a lock on this (am) in such cases, as it
7229 // could cause a potential deadlock, if and when watchdog
7230 // is invoked due to unavailability of lock on am and it
7231 // would prevent watchdog from killing system_server.
7232 if (process == null) {
7233 sb.append("Process: system_server\n");
7234 return;
7235 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007236 // Note: ProcessRecord 'process' is guarded by the service
7237 // instance. (notably process.pkgList, which could otherwise change
7238 // concurrently during execution of this method)
7239 synchronized (this) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007240 if (process.pid == MY_PID) {
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007241 sb.append("Process: system_server\n");
7242 } else {
7243 sb.append("Process: ").append(process.processName).append("\n");
7244 }
Dan Egnora455d192010-03-12 08:52:28 -08007245 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007246 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007247 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7248 for (String pkg : process.pkgList) {
7249 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007250 try {
Dan Egnora455d192010-03-12 08:52:28 -08007251 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7252 if (pi != null) {
7253 sb.append(" v").append(pi.versionCode);
7254 if (pi.versionName != null) {
7255 sb.append(" (").append(pi.versionName).append(")");
7256 }
7257 }
7258 } catch (RemoteException e) {
7259 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007260 }
Dan Egnora455d192010-03-12 08:52:28 -08007261 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007262 }
Dan Egnora455d192010-03-12 08:52:28 -08007263 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007264 }
7265
7266 private static String processClass(ProcessRecord process) {
7267 if (process == null || process.pid == MY_PID) {
7268 return "system_server";
7269 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7270 return "system_app";
7271 } else {
7272 return "data_app";
7273 }
7274 }
7275
7276 /**
7277 * Write a description of an error (crash, WTF, ANR) to the drop box.
7278 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7279 * @param process which caused the error, null means the system server
7280 * @param activity which triggered the error, null if unknown
7281 * @param parent activity related to the error, null if unknown
7282 * @param subject line related to the error, null if absent
7283 * @param report in long form describing the error, null if absent
7284 * @param logFile to include in the report, null if none
7285 * @param crashInfo giving an application stack trace, null if absent
7286 */
7287 public void addErrorToDropBox(String eventType,
7288 ProcessRecord process, ActivityRecord activity, ActivityRecord parent, String subject,
7289 final String report, final File logFile,
7290 final ApplicationErrorReport.CrashInfo crashInfo) {
7291 // NOTE -- this must never acquire the ActivityManagerService lock,
7292 // otherwise the watchdog may be prevented from resetting the system.
7293
7294 final String dropboxTag = processClass(process) + "_" + eventType;
7295 final DropBoxManager dbox = (DropBoxManager)
7296 mContext.getSystemService(Context.DROPBOX_SERVICE);
7297
7298 // Exit early if the dropbox isn't configured to accept this report type.
7299 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7300
7301 final StringBuilder sb = new StringBuilder(1024);
7302 appendDropBoxProcessHeaders(process, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007303 if (activity != null) {
7304 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7305 }
7306 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7307 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7308 }
7309 if (parent != null && parent != activity) {
7310 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7311 }
7312 if (subject != null) {
7313 sb.append("Subject: ").append(subject).append("\n");
7314 }
7315 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007316 if (Debug.isDebuggerConnected()) {
7317 sb.append("Debugger: Connected\n");
7318 }
Dan Egnora455d192010-03-12 08:52:28 -08007319 sb.append("\n");
7320
7321 // Do the rest in a worker thread to avoid blocking the caller on I/O
7322 // (After this point, we shouldn't access AMS internal data structures.)
7323 Thread worker = new Thread("Error dump: " + dropboxTag) {
7324 @Override
7325 public void run() {
7326 if (report != null) {
7327 sb.append(report);
7328 }
7329 if (logFile != null) {
7330 try {
7331 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7332 } catch (IOException e) {
7333 Slog.e(TAG, "Error reading " + logFile, e);
7334 }
7335 }
7336 if (crashInfo != null && crashInfo.stackTrace != null) {
7337 sb.append(crashInfo.stackTrace);
7338 }
7339
7340 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7341 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7342 if (lines > 0) {
7343 sb.append("\n");
7344
7345 // Merge several logcat streams, and take the last N lines
7346 InputStreamReader input = null;
7347 try {
7348 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7349 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7350 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7351
7352 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7353 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7354 input = new InputStreamReader(logcat.getInputStream());
7355
7356 int num;
7357 char[] buf = new char[8192];
7358 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7359 } catch (IOException e) {
7360 Slog.e(TAG, "Error running logcat", e);
7361 } finally {
7362 if (input != null) try { input.close(); } catch (IOException e) {}
7363 }
7364 }
7365
7366 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007367 }
Dan Egnora455d192010-03-12 08:52:28 -08007368 };
7369
7370 if (process == null || process.pid == MY_PID) {
7371 worker.run(); // We may be about to die -- need to run this synchronously
7372 } else {
7373 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007374 }
7375 }
7376
7377 /**
7378 * Bring up the "unexpected error" dialog box for a crashing app.
7379 * Deal with edge cases (intercepts from instrumented applications,
7380 * ActivityController, error intent receivers, that sort of thing).
7381 * @param r the application crashing
7382 * @param crashInfo describing the failure
7383 */
7384 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007385 long timeMillis = System.currentTimeMillis();
7386 String shortMsg = crashInfo.exceptionClassName;
7387 String longMsg = crashInfo.exceptionMessage;
7388 String stackTrace = crashInfo.stackTrace;
7389 if (shortMsg != null && longMsg != null) {
7390 longMsg = shortMsg + ": " + longMsg;
7391 } else if (shortMsg != null) {
7392 longMsg = shortMsg;
7393 }
7394
Dan Egnor60d87622009-12-16 16:32:58 -08007395 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007396 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007397 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007398 try {
7399 String name = r != null ? r.processName : null;
7400 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007401 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007402 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007403 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007404 + " at watcher's request");
7405 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007406 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007407 }
7408 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007409 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007410 }
7411 }
7412
7413 final long origId = Binder.clearCallingIdentity();
7414
7415 // If this process is running instrumentation, finish it.
7416 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007417 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007418 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007419 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7420 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007421 Bundle info = new Bundle();
7422 info.putString("shortMsg", shortMsg);
7423 info.putString("longMsg", longMsg);
7424 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7425 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007426 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007427 }
7428
Dan Egnor60d87622009-12-16 16:32:58 -08007429 // If we can't identify the process or it's already exceeded its crash quota,
7430 // quit right away without showing a crash dialog.
7431 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007432 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007433 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007434 }
7435
7436 Message msg = Message.obtain();
7437 msg.what = SHOW_ERROR_MSG;
7438 HashMap data = new HashMap();
7439 data.put("result", result);
7440 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007441 msg.obj = data;
7442 mHandler.sendMessage(msg);
7443
7444 Binder.restoreCallingIdentity(origId);
7445 }
7446
7447 int res = result.get();
7448
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007449 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007450 synchronized (this) {
7451 if (r != null) {
7452 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7453 SystemClock.uptimeMillis());
7454 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007455 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007456 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007457 }
7458 }
7459
7460 if (appErrorIntent != null) {
7461 try {
7462 mContext.startActivity(appErrorIntent);
7463 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007464 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007466 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007467 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007468
7469 Intent createAppErrorIntentLocked(ProcessRecord r,
7470 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7471 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007472 if (report == null) {
7473 return null;
7474 }
7475 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7476 result.setComponent(r.errorReportReceiver);
7477 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7478 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7479 return result;
7480 }
7481
Dan Egnorb7f03672009-12-09 16:22:32 -08007482 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7483 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007484 if (r.errorReportReceiver == null) {
7485 return null;
7486 }
7487
7488 if (!r.crashing && !r.notResponding) {
7489 return null;
7490 }
7491
Dan Egnorb7f03672009-12-09 16:22:32 -08007492 ApplicationErrorReport report = new ApplicationErrorReport();
7493 report.packageName = r.info.packageName;
7494 report.installerPackageName = r.errorReportReceiver.getPackageName();
7495 report.processName = r.processName;
7496 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007497 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007498
Dan Egnorb7f03672009-12-09 16:22:32 -08007499 if (r.crashing) {
7500 report.type = ApplicationErrorReport.TYPE_CRASH;
7501 report.crashInfo = crashInfo;
7502 } else if (r.notResponding) {
7503 report.type = ApplicationErrorReport.TYPE_ANR;
7504 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007505
Dan Egnorb7f03672009-12-09 16:22:32 -08007506 report.anrInfo.activity = r.notRespondingReport.tag;
7507 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7508 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007509 }
7510
Dan Egnorb7f03672009-12-09 16:22:32 -08007511 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007512 }
7513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007514 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7515 // assume our apps are happy - lazy create the list
7516 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7517
7518 synchronized (this) {
7519
7520 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007521 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7522 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007523 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7524 // This one's in trouble, so we'll generate a report for it
7525 // crashes are higher priority (in case there's a crash *and* an anr)
7526 ActivityManager.ProcessErrorStateInfo report = null;
7527 if (app.crashing) {
7528 report = app.crashingReport;
7529 } else if (app.notResponding) {
7530 report = app.notRespondingReport;
7531 }
7532
7533 if (report != null) {
7534 if (errList == null) {
7535 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7536 }
7537 errList.add(report);
7538 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007539 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007540 " crashing = " + app.crashing +
7541 " notResponding = " + app.notResponding);
7542 }
7543 }
7544 }
7545 }
7546
7547 return errList;
7548 }
7549
7550 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7551 // Lazy instantiation of list
7552 List<ActivityManager.RunningAppProcessInfo> runList = null;
7553 synchronized (this) {
7554 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007555 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7556 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007557 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7558 // Generate process state info for running application
7559 ActivityManager.RunningAppProcessInfo currApp =
7560 new ActivityManager.RunningAppProcessInfo(app.processName,
7561 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007562 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007563 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007564 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007565 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007566 if (app.persistent) {
7567 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007569 int adj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007570 if (adj >= ProcessList.EMPTY_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007571 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_EMPTY;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007572 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007573 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007574 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7575 } else if (adj >= ProcessList.HOME_APP_ADJ) {
The Android Open Source Project4df24232009-03-05 14:34:35 -08007576 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
7577 currApp.lru = 0;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007578 } else if (adj >= ProcessList.SECONDARY_SERVER_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007579 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007580 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackborn5383f502010-10-22 12:59:20 -07007581 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007582 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007583 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
Dianne Hackborn7d608422011-08-07 16:24:18 -07007584 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007585 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7586 } else {
7587 currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7588 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007589 currApp.importanceReasonCode = app.adjTypeCode;
7590 if (app.adjSource instanceof ProcessRecord) {
7591 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007592 } else if (app.adjSource instanceof ActivityRecord) {
7593 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007594 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7595 }
7596 if (app.adjTarget instanceof ComponentName) {
7597 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7598 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007599 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007600 // + " lru=" + currApp.lru);
7601 if (runList == null) {
7602 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7603 }
7604 runList.add(currApp);
7605 }
7606 }
7607 }
7608 return runList;
7609 }
7610
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007611 public List<ApplicationInfo> getRunningExternalApplications() {
7612 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7613 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7614 if (runningApps != null && runningApps.size() > 0) {
7615 Set<String> extList = new HashSet<String>();
7616 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7617 if (app.pkgList != null) {
7618 for (String pkg : app.pkgList) {
7619 extList.add(pkg);
7620 }
7621 }
7622 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007623 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007624 for (String pkg : extList) {
7625 try {
7626 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7627 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7628 retList.add(info);
7629 }
7630 } catch (RemoteException e) {
7631 }
7632 }
7633 }
7634 return retList;
7635 }
7636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007637 @Override
7638 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007639 if (checkCallingPermission(android.Manifest.permission.DUMP)
7640 != PackageManager.PERMISSION_GRANTED) {
7641 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7642 + Binder.getCallingPid()
7643 + ", uid=" + Binder.getCallingUid()
7644 + " without permission "
7645 + android.Manifest.permission.DUMP);
7646 return;
7647 }
7648
7649 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007650 boolean dumpClient = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007651
7652 int opti = 0;
7653 while (opti < args.length) {
7654 String opt = args[opti];
7655 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7656 break;
7657 }
7658 opti++;
7659 if ("-a".equals(opt)) {
7660 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007661 } else if ("-c".equals(opt)) {
7662 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007663 } else if ("-h".equals(opt)) {
7664 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007665 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007666 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007667 pw.println(" a[ctivities]: activity stack state");
7668 pw.println(" b[roadcasts]: broadcast state");
7669 pw.println(" i[ntents]: pending intent state");
7670 pw.println(" p[rocesses]: process state");
7671 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007672 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7673 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007674 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007675 pw.println(" all: dump all activities");
7676 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007677 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007678 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7679 pw.println(" a partial substring in a component name, a");
7680 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007681 pw.println(" -a: include all available server state.");
7682 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007683 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007684 } else {
7685 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007686 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007687 }
7688
7689 // Is the caller requesting to dump a particular piece of data?
7690 if (opti < args.length) {
7691 String cmd = args[opti];
7692 opti++;
7693 if ("activities".equals(cmd) || "a".equals(cmd)) {
7694 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007695 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007696 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007697 return;
7698 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
7699 synchronized (this) {
7700 dumpBroadcastsLocked(fd, pw, args, opti, true);
7701 }
7702 return;
7703 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
7704 synchronized (this) {
7705 dumpPendingIntentsLocked(fd, pw, args, opti, true);
7706 }
7707 return;
7708 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
7709 synchronized (this) {
7710 dumpProcessesLocked(fd, pw, args, opti, true);
7711 }
7712 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07007713 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
7714 synchronized (this) {
7715 dumpOomLocked(fd, pw, args, opti, true);
7716 }
7717 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007718 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
7719 synchronized (this) {
7720 dumpProvidersLocked(fd, pw, args, opti, true);
7721 }
7722 return;
7723 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007724 String[] newArgs;
7725 String name;
7726 if (opti >= args.length) {
7727 name = null;
7728 newArgs = EMPTY_STRING_ARRAY;
7729 } else {
7730 name = args[opti];
7731 opti++;
7732 newArgs = new String[args.length - opti];
7733 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
7734 }
7735 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
7736 pw.println("No services match: " + name);
7737 pw.println("Use -h for help.");
7738 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007739 return;
7740 } else if ("services".equals(cmd) || "s".equals(cmd)) {
7741 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007742 dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007743 }
7744 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07007745 } else {
7746 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007747 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
7748 pw.println("Bad activity command, or no activities match: " + cmd);
7749 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07007750 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08007751 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007752 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007753 }
7754
7755 // No piece of data specified, dump everything.
7756 synchronized (this) {
7757 boolean needSep;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007758 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007759 if (needSep) {
7760 pw.println(" ");
7761 }
7762 if (dumpAll) {
7763 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007764 }
7765 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
7766 if (needSep) {
7767 pw.println(" ");
7768 }
7769 if (dumpAll) {
7770 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007771 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007772 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007773 if (needSep) {
7774 pw.println(" ");
7775 }
7776 if (dumpAll) {
7777 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007778 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007779 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007780 if (needSep) {
7781 pw.println(" ");
7782 }
7783 if (dumpAll) {
7784 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007785 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007786 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007787 if (needSep) {
7788 pw.println(" ");
7789 }
7790 if (dumpAll) {
7791 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007792 }
7793 dumpProcessesLocked(fd, pw, args, opti, dumpAll);
7794 }
7795 }
7796
7797 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007798 int opti, boolean dumpAll, boolean dumpClient) {
7799 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
7800 pw.println(" Main stack:");
7801 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007802 pw.println(" ");
7803 pw.println(" Running activities (most recent first):");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007804 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007805 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007806 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007807 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007808 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
7809 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007810 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007811 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007812 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007813 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007814 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
7815 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007816 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007817 if (mMainStack.mGoingToSleepActivities.size() > 0) {
7818 pw.println(" ");
7819 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007820 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
7821 !dumpAll, false);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007822 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007823 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007824 pw.println(" ");
7825 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007826 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
7827 !dumpAll, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007829
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007830 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007831 if (mMainStack.mPausingActivity != null) {
7832 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
7833 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007834 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007835 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007836 if (dumpAll) {
7837 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
7838 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
7839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007840
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007841 if (mRecentTasks.size() > 0) {
7842 pw.println();
7843 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007844
7845 final int N = mRecentTasks.size();
7846 for (int i=0; i<N; i++) {
7847 TaskRecord tr = mRecentTasks.get(i);
7848 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
7849 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007850 if (dumpAll) {
7851 mRecentTasks.get(i).dump(pw, " ");
7852 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007853 }
7854 }
7855
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007856 if (dumpAll) {
7857 pw.println(" ");
7858 pw.println(" mCurTask: " + mCurTask);
7859 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007860
7861 return true;
7862 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07007863
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007864 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
7865 int opti, boolean dumpAll) {
7866 boolean needSep = false;
7867 int numPers = 0;
7868
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007869 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
7870
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007871 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007872 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
7873 final int NA = procs.size();
7874 for (int ia=0; ia<NA; ia++) {
7875 if (!needSep) {
7876 pw.println(" All known processes:");
7877 needSep = true;
7878 }
7879 ProcessRecord r = procs.valueAt(ia);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07007880 pw.print(r.persistent ? " *PERS*" : " *APP*");
7881 pw.print(" UID "); pw.print(procs.keyAt(ia));
7882 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007883 r.dump(pw, " ");
7884 if (r.persistent) {
7885 numPers++;
7886 }
7887 }
7888 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007889 }
7890
7891 if (mLruProcesses.size() > 0) {
7892 if (needSep) pw.println(" ");
7893 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007894 pw.println(" Process LRU list (most recent first):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007895 dumpProcessOomList(pw, this, mLruProcesses, " ",
7896 "Proc", "PERS", false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007897 needSep = true;
7898 }
7899
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007900 if (dumpAll) {
7901 synchronized (mPidsSelfLocked) {
7902 if (mPidsSelfLocked.size() > 0) {
7903 if (needSep) pw.println(" ");
7904 needSep = true;
7905 pw.println(" PID mappings:");
7906 for (int i=0; i<mPidsSelfLocked.size(); i++) {
7907 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
7908 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
7909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007910 }
7911 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007912 }
7913
7914 if (mForegroundProcesses.size() > 0) {
7915 if (needSep) pw.println(" ");
7916 needSep = true;
7917 pw.println(" Foreground Processes:");
7918 for (int i=0; i<mForegroundProcesses.size(); i++) {
7919 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
7920 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007921 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007922 }
7923
7924 if (mPersistentStartingProcesses.size() > 0) {
7925 if (needSep) pw.println(" ");
7926 needSep = true;
7927 pw.println(" Persisent processes that are starting:");
7928 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007929 "Starting Norm", "Restarting PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007931
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007932 if (mRemovedProcesses.size() > 0) {
7933 if (needSep) pw.println(" ");
7934 needSep = true;
7935 pw.println(" Processes that are being removed:");
7936 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007937 "Removed Norm", "Removed PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007938 }
7939
7940 if (mProcessesOnHold.size() > 0) {
7941 if (needSep) pw.println(" ");
7942 needSep = true;
7943 pw.println(" Processes that are on old until the system is ready:");
7944 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackborn287952c2010-09-22 22:34:31 -07007945 "OnHold Norm", "OnHold PERS");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007947
Dianne Hackborn287952c2010-09-22 22:34:31 -07007948 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007949
7950 if (mProcessCrashTimes.getMap().size() > 0) {
7951 if (needSep) pw.println(" ");
7952 needSep = true;
7953 pw.println(" Time since processes crashed:");
7954 long now = SystemClock.uptimeMillis();
7955 for (Map.Entry<String, SparseArray<Long>> procs
7956 : mProcessCrashTimes.getMap().entrySet()) {
7957 SparseArray<Long> uids = procs.getValue();
7958 final int N = uids.size();
7959 for (int i=0; i<N; i++) {
7960 pw.print(" Process "); pw.print(procs.getKey());
7961 pw.print(" uid "); pw.print(uids.keyAt(i));
7962 pw.print(": last crashed ");
7963 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007964 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07007965 }
7966 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007968
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007969 if (mBadProcesses.getMap().size() > 0) {
7970 if (needSep) pw.println(" ");
7971 needSep = true;
7972 pw.println(" Bad processes:");
7973 for (Map.Entry<String, SparseArray<Long>> procs
7974 : mBadProcesses.getMap().entrySet()) {
7975 SparseArray<Long> uids = procs.getValue();
7976 final int N = uids.size();
7977 for (int i=0; i<N; i++) {
7978 pw.print(" Bad process "); pw.print(procs.getKey());
7979 pw.print(" uid "); pw.print(uids.keyAt(i));
7980 pw.print(": crashed at time ");
7981 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007982 }
7983 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007985
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007986 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007987 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07007988 if (mHeavyWeightProcess != null) {
7989 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
7990 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007991 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007992 if (dumpAll) {
7993 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07007994 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07007995 pw.println(" mScreenCompatPackages:");
7996 for (Map.Entry<String, Integer> entry
7997 : mCompatModePackages.getPackages().entrySet()) {
7998 String pkg = entry.getKey();
7999 int mode = entry.getValue();
8000 pw.print(" "); pw.print(pkg); pw.print(": ");
8001 pw.print(mode); pw.println();
8002 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008003 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008004 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008005 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8006 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8007 || mOrigWaitForDebugger) {
8008 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8009 + " mDebugTransient=" + mDebugTransient
8010 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8011 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008012 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8013 || mProfileFd != null) {
8014 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8015 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8016 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8017 + mAutoStopProfiler);
8018 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008019 if (mAlwaysFinishActivities || mController != null) {
8020 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8021 + " mController=" + mController);
8022 }
8023 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008024 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008025 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008026 + " mProcessesReady=" + mProcessesReady
8027 + " mSystemReady=" + mSystemReady);
8028 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008029 + " mBooted=" + mBooted
8030 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008031 pw.print(" mLastPowerCheckRealtime=");
8032 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8033 pw.println("");
8034 pw.print(" mLastPowerCheckUptime=");
8035 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8036 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008037 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8038 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008039 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008040 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008041
8042 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043 }
8044
Dianne Hackborn287952c2010-09-22 22:34:31 -07008045 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
8046 int opti, boolean needSep, boolean dumpAll) {
8047 if (mProcessesToGc.size() > 0) {
8048 if (needSep) pw.println(" ");
8049 needSep = true;
8050 pw.println(" Processes that are waiting to GC:");
8051 long now = SystemClock.uptimeMillis();
8052 for (int i=0; i<mProcessesToGc.size(); i++) {
8053 ProcessRecord proc = mProcessesToGc.get(i);
8054 pw.print(" Process "); pw.println(proc);
8055 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8056 pw.print(", last gced=");
8057 pw.print(now-proc.lastRequestedGc);
8058 pw.print(" ms ago, last lowMem=");
8059 pw.print(now-proc.lastLowMemory);
8060 pw.println(" ms ago");
8061
8062 }
8063 }
8064 return needSep;
8065 }
8066
8067 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8068 int opti, boolean dumpAll) {
8069 boolean needSep = false;
8070
8071 if (mLruProcesses.size() > 0) {
8072 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
8073
8074 Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
8075 @Override
8076 public int compare(ProcessRecord object1, ProcessRecord object2) {
8077 if (object1.setAdj != object2.setAdj) {
8078 return object1.setAdj > object2.setAdj ? -1 : 1;
8079 }
8080 if (object1.setSchedGroup != object2.setSchedGroup) {
8081 return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
8082 }
8083 if (object1.keeping != object2.keeping) {
8084 return object1.keeping ? -1 : 1;
8085 }
8086 if (object1.pid != object2.pid) {
8087 return object1.pid > object2.pid ? -1 : 1;
8088 }
8089 return 0;
8090 }
8091 };
8092
8093 Collections.sort(procs, comparator);
8094
8095 if (needSep) pw.println(" ");
8096 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008097 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008098 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
8099 pw.print(" CORE_SERVER_ADJ: "); pw.println(ProcessList.CORE_SERVER_ADJ);
8100 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8101 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8102 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8103 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8104 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
8105 pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(ProcessList.SECONDARY_SERVER_ADJ);
8106 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
8107 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
8108 pw.print(" EMPTY_APP_ADJ: "); pw.println(ProcessList.EMPTY_APP_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008109
8110 if (needSep) pw.println(" ");
8111 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008112 pw.println(" Process OOM control:");
8113 dumpProcessOomList(pw, this, procs, " ",
8114 "Proc", "PERS", true);
8115 needSep = true;
8116 }
8117
8118 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
8119
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008120 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008121 pw.println(" mHomeProcess: " + mHomeProcess);
8122 if (mHeavyWeightProcess != null) {
8123 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8124 }
8125
8126 return true;
8127 }
8128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008129 /**
8130 * There are three ways to call this:
8131 * - no service specified: dump all the services
8132 * - a flattened component name that matched an existing service was specified as the
8133 * first arg: dump that one service
8134 * - the first arg isn't the flattened component name of an existing service:
8135 * dump all services whose component contains the first arg as a substring
8136 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008137 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8138 int opti, boolean dumpAll) {
8139 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008141 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008142 synchronized (this) {
8143 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008144 services.add(r1);
8145 }
8146 }
8147 } else {
8148 ComponentName componentName = name != null
8149 ? ComponentName.unflattenFromString(name) : null;
8150 int objectId = 0;
8151 if (componentName == null) {
8152 // Not a '/' separated full component name; maybe an object ID?
8153 try {
8154 objectId = Integer.parseInt(name, 16);
8155 name = null;
8156 componentName = null;
8157 } catch (RuntimeException e) {
8158 }
8159 }
8160
8161 synchronized (this) {
8162 for (ServiceRecord r1 : mServices.values()) {
8163 if (componentName != null) {
8164 if (r1.name.equals(componentName)) {
8165 services.add(r1);
8166 }
8167 } else if (name != null) {
8168 if (r1.name.flattenToString().contains(name)) {
8169 services.add(r1);
8170 }
8171 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008172 services.add(r1);
8173 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174 }
8175 }
8176 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008177
8178 if (services.size() <= 0) {
8179 return false;
8180 }
8181
8182 boolean needSep = false;
8183 for (int i=0; i<services.size(); i++) {
8184 if (needSep) {
8185 pw.println();
8186 }
8187 needSep = true;
8188 dumpService("", fd, pw, services.get(i), args, dumpAll);
8189 }
8190 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008191 }
8192
8193 /**
8194 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8195 * there is a thread associated with the service.
8196 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008197 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8198 final ServiceRecord r, String[] args, boolean dumpAll) {
8199 String innerPrefix = prefix + " ";
8200 synchronized (this) {
8201 pw.print(prefix); pw.print("SERVICE ");
8202 pw.print(r.shortName); pw.print(" ");
8203 pw.print(Integer.toHexString(System.identityHashCode(r)));
8204 pw.print(" pid=");
8205 if (r.app != null) pw.println(r.app.pid);
8206 else pw.println("(not running)");
8207 if (dumpAll) {
8208 r.dump(pw, innerPrefix);
8209 }
8210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008211 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008212 pw.print(prefix); pw.println(" Client:");
8213 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008214 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008215 TransferPipe tp = new TransferPipe();
8216 try {
8217 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8218 tp.setBufferPrefix(prefix + " ");
8219 tp.go(fd);
8220 } finally {
8221 tp.kill();
8222 }
8223 } catch (IOException e) {
8224 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008225 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008226 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008227 }
8228 }
8229 }
8230
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008231 static class ItemMatcher {
8232 ArrayList<ComponentName> components;
8233 ArrayList<String> strings;
8234 ArrayList<Integer> objects;
8235 boolean all;
8236
8237 ItemMatcher() {
8238 all = true;
8239 }
8240
8241 void build(String name) {
8242 ComponentName componentName = ComponentName.unflattenFromString(name);
8243 if (componentName != null) {
8244 if (components == null) {
8245 components = new ArrayList<ComponentName>();
8246 }
8247 components.add(componentName);
8248 all = false;
8249 } else {
8250 int objectId = 0;
8251 // Not a '/' separated full component name; maybe an object ID?
8252 try {
8253 objectId = Integer.parseInt(name, 16);
8254 if (objects == null) {
8255 objects = new ArrayList<Integer>();
8256 }
8257 objects.add(objectId);
8258 all = false;
8259 } catch (RuntimeException e) {
8260 // Not an integer; just do string match.
8261 if (strings == null) {
8262 strings = new ArrayList<String>();
8263 }
8264 strings.add(name);
8265 all = false;
8266 }
8267 }
8268 }
8269
8270 int build(String[] args, int opti) {
8271 for (; opti<args.length; opti++) {
8272 String name = args[opti];
8273 if ("--".equals(name)) {
8274 return opti+1;
8275 }
8276 build(name);
8277 }
8278 return opti;
8279 }
8280
8281 boolean match(Object object, ComponentName comp) {
8282 if (all) {
8283 return true;
8284 }
8285 if (components != null) {
8286 for (int i=0; i<components.size(); i++) {
8287 if (components.get(i).equals(comp)) {
8288 return true;
8289 }
8290 }
8291 }
8292 if (objects != null) {
8293 for (int i=0; i<objects.size(); i++) {
8294 if (System.identityHashCode(object) == objects.get(i)) {
8295 return true;
8296 }
8297 }
8298 }
8299 if (strings != null) {
8300 String flat = comp.flattenToString();
8301 for (int i=0; i<strings.size(); i++) {
8302 if (flat.contains(strings.get(i))) {
8303 return true;
8304 }
8305 }
8306 }
8307 return false;
8308 }
8309 }
8310
Dianne Hackborn625ac272010-09-17 18:29:22 -07008311 /**
8312 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008313 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008314 * - the cmd arg isn't the flattened component name of an existing activity:
8315 * dump all activity whose component contains the cmd as a substring
8316 * - A hex number of the ActivityRecord object instance.
8317 */
8318 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8319 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008320 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008321
8322 if ("all".equals(name)) {
8323 synchronized (this) {
8324 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008325 activities.add(r1);
8326 }
8327 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008328 } else if ("top".equals(name)) {
8329 synchronized (this) {
8330 final int N = mMainStack.mHistory.size();
8331 if (N > 0) {
8332 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8333 }
8334 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008335 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008336 ItemMatcher matcher = new ItemMatcher();
8337 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008338
8339 synchronized (this) {
8340 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008341 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008342 activities.add(r1);
8343 }
8344 }
8345 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008346 }
8347
8348 if (activities.size() <= 0) {
8349 return false;
8350 }
8351
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008352 String[] newArgs = new String[args.length - opti];
8353 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8354
Dianne Hackborn30d71892010-12-11 10:37:55 -08008355 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008356 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008357 for (int i=activities.size()-1; i>=0; i--) {
8358 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008359 if (needSep) {
8360 pw.println();
8361 }
8362 needSep = true;
8363 synchronized (this) {
8364 if (lastTask != r.task) {
8365 lastTask = r.task;
8366 pw.print("TASK "); pw.print(lastTask.affinity);
8367 pw.print(" id="); pw.println(lastTask.taskId);
8368 if (dumpAll) {
8369 lastTask.dump(pw, " ");
8370 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008371 }
8372 }
8373 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008374 }
8375 return true;
8376 }
8377
8378 /**
8379 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8380 * there is a thread associated with the activity.
8381 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008382 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008383 final ActivityRecord r, String[] args, boolean dumpAll) {
8384 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008385 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008386 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8387 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8388 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008389 if (r.app != null) pw.println(r.app.pid);
8390 else pw.println("(not running)");
8391 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008392 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008393 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008394 }
8395 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008396 // flush anything that is already in the PrintWriter since the thread is going
8397 // to write to the file descriptor directly
8398 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008399 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008400 TransferPipe tp = new TransferPipe();
8401 try {
8402 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8403 innerPrefix, args);
8404 tp.go(fd);
8405 } finally {
8406 tp.kill();
8407 }
8408 } catch (IOException e) {
8409 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008410 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008411 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008412 }
8413 }
8414 }
8415
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008416 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8417 int opti, boolean dumpAll) {
8418 boolean needSep = false;
8419
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008420 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008421 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008422 if (mRegisteredReceivers.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008423 pw.println(" Registered Receivers:");
8424 Iterator it = mRegisteredReceivers.values().iterator();
8425 while (it.hasNext()) {
8426 ReceiverList r = (ReceiverList)it.next();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008427 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008428 r.dump(pw, " ");
8429 }
8430 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008431
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008432 pw.println();
8433 pw.println(" Receiver Resolver Table:");
8434 mReceiverResolver.dump(pw, null, " ", null, false);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008435 needSep = true;
8436 }
8437
8438 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8439 || mPendingBroadcast != null) {
8440 if (mParallelBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008441 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008442 pw.println(" Active broadcasts:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008443 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008444 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
8445 pw.println(" Broadcast #" + i + ":");
8446 mParallelBroadcasts.get(i).dump(pw, " ");
8447 }
8448 if (mOrderedBroadcasts.size() > 0) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008449 pw.println();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07008450 pw.println(" Active ordered broadcasts:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008451 }
8452 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
8453 pw.println(" Serialized Broadcast #" + i + ":");
8454 mOrderedBroadcasts.get(i).dump(pw, " ");
8455 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008456 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008457 pw.println(" Pending broadcast:");
8458 if (mPendingBroadcast != null) {
8459 mPendingBroadcast.dump(pw, " ");
8460 } else {
8461 pw.println(" (null)");
8462 }
8463 needSep = true;
8464 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008465
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008466 if (needSep) {
8467 pw.println();
8468 }
8469 pw.println(" Historical broadcasts:");
8470 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8471 BroadcastRecord r = mBroadcastHistory[i];
8472 if (r == null) {
8473 break;
8474 }
8475 if (dumpAll) {
8476 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8477 r.dump(pw, " ");
8478 } else {
8479 if (i >= 50) {
8480 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008481 break;
8482 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008483 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008484 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008485 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008486 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008487
8488 if (mStickyBroadcasts != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008489 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008490 pw.println(" Sticky broadcasts:");
8491 StringBuilder sb = new StringBuilder(128);
8492 for (Map.Entry<String, ArrayList<Intent>> ent
8493 : mStickyBroadcasts.entrySet()) {
8494 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008495 if (dumpAll) {
8496 pw.println(":");
8497 ArrayList<Intent> intents = ent.getValue();
8498 final int N = intents.size();
8499 for (int i=0; i<N; i++) {
8500 sb.setLength(0);
8501 sb.append(" Intent: ");
8502 intents.get(i).toShortString(sb, true, false);
8503 pw.println(sb.toString());
8504 Bundle bundle = intents.get(i).getExtras();
8505 if (bundle != null) {
8506 pw.print(" ");
8507 pw.println(bundle.toString());
8508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008509 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008510 } else {
8511 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008512 }
8513 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008514 needSep = true;
8515 }
8516
8517 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008518 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008519 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008520 pw.println(" mHandler:");
8521 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008522 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008523 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008524
8525 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008526 }
8527
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008528 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008529 int opti, boolean dumpAll, boolean dumpClient) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008530 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008531
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008532 ItemMatcher matcher = new ItemMatcher();
8533 matcher.build(args, opti);
8534
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008535 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8536 if (mServices.size() > 0) {
8537 pw.println(" Active services:");
8538 long nowReal = SystemClock.elapsedRealtime();
8539 Iterator<ServiceRecord> it = mServices.values().iterator();
8540 needSep = false;
8541 while (it.hasNext()) {
8542 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008543 if (!matcher.match(r, r.name)) {
8544 continue;
8545 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008546 if (needSep) {
8547 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008549 pw.print(" * "); pw.println(r);
8550 if (dumpAll) {
8551 r.dump(pw, " ");
8552 needSep = true;
8553 } else {
8554 pw.print(" app="); pw.println(r.app);
8555 pw.print(" created=");
8556 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8557 pw.print(" started="); pw.print(r.startRequested);
8558 pw.print(" connections="); pw.println(r.connections.size());
8559 }
8560 if (dumpClient && r.app != null && r.app.thread != null) {
8561 pw.println(" Client:");
8562 pw.flush();
8563 try {
8564 TransferPipe tp = new TransferPipe();
8565 try {
8566 r.app.thread.dumpService(
8567 tp.getWriteFd().getFileDescriptor(), r, args);
8568 tp.setBufferPrefix(" ");
8569 // Short timeout, since blocking here can
8570 // deadlock with the application.
8571 tp.go(fd, 2000);
8572 } finally {
8573 tp.kill();
8574 }
8575 } catch (IOException e) {
8576 pw.println(" Failure while dumping the service: " + e);
8577 } catch (RemoteException e) {
8578 pw.println(" Got a RemoteException while dumping the service");
8579 }
8580 needSep = true;
8581 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008582 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008583 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008584 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008585
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008586 if (mPendingServices.size() > 0) {
8587 if (needSep) pw.println(" ");
8588 pw.println(" Pending services:");
8589 for (int i=0; i<mPendingServices.size(); i++) {
8590 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008591 if (!matcher.match(r, r.name)) {
8592 continue;
8593 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008594 pw.print(" * Pending "); pw.println(r);
8595 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008596 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008597 needSep = true;
8598 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008599
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008600 if (mRestartingServices.size() > 0) {
8601 if (needSep) pw.println(" ");
8602 pw.println(" Restarting services:");
8603 for (int i=0; i<mRestartingServices.size(); i++) {
8604 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008605 if (!matcher.match(r, r.name)) {
8606 continue;
8607 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008608 pw.print(" * Restarting "); pw.println(r);
8609 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008610 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008611 needSep = true;
8612 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008613
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008614 if (mStoppingServices.size() > 0) {
8615 if (needSep) pw.println(" ");
8616 pw.println(" Stopping services:");
8617 for (int i=0; i<mStoppingServices.size(); i++) {
8618 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008619 if (!matcher.match(r, r.name)) {
8620 continue;
8621 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008622 pw.print(" * Stopping "); pw.println(r);
8623 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008624 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008625 needSep = true;
8626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008627
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008628 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008629 if (mServiceConnections.size() > 0) {
8630 if (needSep) pw.println(" ");
8631 pw.println(" Connection bindings to services:");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008632 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008633 = mServiceConnections.values().iterator();
8634 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008635 ArrayList<ConnectionRecord> r = it.next();
8636 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008637 ConnectionRecord cr = r.get(i);
8638 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
8639 continue;
8640 }
8641 pw.print(" * "); pw.println(cr);
8642 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07008643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008645 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008646 }
8647 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008648
8649 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008650 }
8651
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008652 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8653 int opti, boolean dumpAll) {
8654 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008656 ItemMatcher matcher = new ItemMatcher();
8657 matcher.build(args, opti);
8658
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008659 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
8660 if (mProvidersByClass.size() > 0) {
8661 if (needSep) pw.println(" ");
8662 pw.println(" Published content providers (by class):");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008663 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008664 = mProvidersByClass.entrySet().iterator();
8665 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008666 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008667 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008668 ComponentName comp = e.getKey();
8669 String cls = comp.getClassName();
8670 int end = cls.lastIndexOf('.');
8671 if (end > 0 && end < (cls.length()-2)) {
8672 cls = cls.substring(end+1);
8673 }
8674 if (!matcher.match(r, comp)) {
8675 continue;
8676 }
8677 pw.print(" * "); pw.print(cls); pw.print(" (");
8678 pw.print(comp.flattenToShortString()); pw.print(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008679 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008680 pw.println();
8681 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008682 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008683 pw.print(" * "); pw.print(e.getKey().flattenToShortString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008684 if (r.app != null) {
8685 pw.println(":");
8686 pw.print(" "); pw.println(r.app);
8687 } else {
8688 pw.println();
8689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008691 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008692 needSep = true;
8693 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008694
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008695 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008696 if (mProvidersByName.size() > 0) {
8697 pw.println(" ");
8698 pw.println(" Authority to provider mappings:");
Dianne Hackborn860755f2010-06-03 18:47:52 -07008699 Iterator<Map.Entry<String, ContentProviderRecord>> it
8700 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008701 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008702 Map.Entry<String, ContentProviderRecord> e = it.next();
8703 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008704 if (!matcher.match(r, r.name)) {
8705 continue;
8706 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008707 pw.print(" "); pw.print(e.getKey()); pw.print(": ");
8708 pw.println(r);
8709 }
8710 needSep = true;
8711 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008712 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008713
8714 if (mLaunchingProviders.size() > 0) {
8715 if (needSep) pw.println(" ");
8716 pw.println(" Launching content providers:");
8717 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
8718 pw.print(" Launching #"); pw.print(i); pw.print(": ");
8719 pw.println(mLaunchingProviders.get(i));
8720 }
8721 needSep = true;
8722 }
8723
8724 if (mGrantedUriPermissions.size() > 0) {
8725 pw.println();
8726 pw.println("Granted Uri Permissions:");
8727 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
8728 int uid = mGrantedUriPermissions.keyAt(i);
8729 HashMap<Uri, UriPermission> perms
8730 = mGrantedUriPermissions.valueAt(i);
8731 pw.print(" * UID "); pw.print(uid);
8732 pw.println(" holds:");
8733 for (UriPermission perm : perms.values()) {
8734 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008735 if (dumpAll) {
8736 perm.dump(pw, " ");
8737 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008738 }
8739 }
8740 needSep = true;
8741 }
8742
8743 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008744 }
8745
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008746 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8747 int opti, boolean dumpAll) {
8748 boolean needSep = false;
8749
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008750 if (this.mIntentSenderRecords.size() > 0) {
8751 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
8752 Iterator<WeakReference<PendingIntentRecord>> it
8753 = mIntentSenderRecords.values().iterator();
8754 while (it.hasNext()) {
8755 WeakReference<PendingIntentRecord> ref = it.next();
8756 PendingIntentRecord rec = ref != null ? ref.get(): null;
8757 needSep = true;
8758 if (rec != null) {
8759 pw.print(" * "); pw.println(rec);
8760 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008761 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008762 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008763 } else {
8764 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008765 }
8766 }
8767 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008768
8769 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008770 }
8771
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008772 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
8773 String prefix, String label, boolean complete, boolean brief, boolean client) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008774 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008775 boolean needNL = false;
8776 final String innerPrefix = prefix + " ";
8777 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008778 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008779 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07008780 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008781 if (needNL) {
8782 pw.println(" ");
8783 needNL = false;
8784 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008785 if (lastTask != r.task) {
8786 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008787 pw.print(prefix);
8788 pw.print(full ? "* " : " ");
8789 pw.println(lastTask);
8790 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008791 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008792 } else if (complete) {
8793 // Complete + brief == give a summary. Isn't that obvious?!?
8794 if (lastTask.intent != null) {
8795 pw.print(prefix); pw.print(" "); pw.println(lastTask.intent);
8796 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008797 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008798 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008799 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
8800 pw.print(" #"); pw.print(i); pw.print(": ");
8801 pw.println(r);
8802 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008803 r.dump(pw, innerPrefix);
8804 } else if (complete) {
8805 // Complete + brief == give a summary. Isn't that obvious?!?
8806 pw.print(innerPrefix); pw.println(r.intent);
8807 if (r.app != null) {
8808 pw.print(innerPrefix); pw.println(r.app);
8809 }
8810 }
8811 if (client && r.app != null && r.app.thread != null) {
8812 // flush anything that is already in the PrintWriter since the thread is going
8813 // to write to the file descriptor directly
8814 pw.flush();
8815 try {
8816 TransferPipe tp = new TransferPipe();
8817 try {
8818 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(), r,
8819 innerPrefix, args);
8820 // Short timeout, since blocking here can
8821 // deadlock with the application.
8822 tp.go(fd, 2000);
8823 } finally {
8824 tp.kill();
8825 }
8826 } catch (IOException e) {
8827 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
8828 } catch (RemoteException e) {
8829 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
8830 }
8831 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07008832 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008833 }
8834 }
8835
Dianne Hackborn09c916b2009-12-08 14:50:51 -08008836 private static String buildOomTag(String prefix, String space, int val, int base) {
8837 if (val == base) {
8838 if (space == null) return prefix;
8839 return prefix + " ";
8840 }
8841 return prefix + "+" + Integer.toString(val-base);
8842 }
8843
8844 private static final int dumpProcessList(PrintWriter pw,
8845 ActivityManagerService service, List list,
Dianne Hackborn287952c2010-09-22 22:34:31 -07008846 String prefix, String normalLabel, String persistentLabel) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008847 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008848 final int N = list.size()-1;
8849 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008850 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008851 pw.println(String.format("%s%s #%2d: %s",
8852 prefix, (r.persistent ? persistentLabel : normalLabel),
8853 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008854 if (r.persistent) {
8855 numPers++;
8856 }
8857 }
8858 return numPers;
8859 }
8860
Dianne Hackborn287952c2010-09-22 22:34:31 -07008861 private static final void dumpProcessOomList(PrintWriter pw,
8862 ActivityManagerService service, List<ProcessRecord> list,
8863 String prefix, String normalLabel, String persistentLabel,
8864 boolean inclDetails) {
8865
8866 final long curRealtime = SystemClock.elapsedRealtime();
8867 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
8868 final long curUptime = SystemClock.uptimeMillis();
8869 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
8870
8871 final int N = list.size()-1;
8872 for (int i=N; i>=0; i--) {
8873 ProcessRecord r = list.get(i);
8874 String oomAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -07008875 if (r.setAdj >= ProcessList.EMPTY_APP_ADJ) {
8876 oomAdj = buildOomTag("empty", null, r.setAdj, ProcessList.EMPTY_APP_ADJ);
8877 } else if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
8878 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
8879 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
8880 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
8881 } else if (r.setAdj >= ProcessList.SECONDARY_SERVER_ADJ) {
8882 oomAdj = buildOomTag("svc", " ", r.setAdj, ProcessList.SECONDARY_SERVER_ADJ);
8883 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
8884 oomAdj = buildOomTag("bckup", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
8885 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8886 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
8887 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8888 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
8889 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
8890 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
8891 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
8892 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
8893 } else if (r.setAdj >= ProcessList.CORE_SERVER_ADJ) {
8894 oomAdj = buildOomTag("core ", null, r.setAdj, ProcessList.CORE_SERVER_ADJ);
8895 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
8896 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008897 } else {
8898 oomAdj = Integer.toString(r.setAdj);
8899 }
8900 String schedGroup;
8901 switch (r.setSchedGroup) {
8902 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
8903 schedGroup = "B";
8904 break;
8905 case Process.THREAD_GROUP_DEFAULT:
8906 schedGroup = "F";
8907 break;
8908 default:
8909 schedGroup = Integer.toString(r.setSchedGroup);
8910 break;
8911 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07008912 String foreground;
8913 if (r.foregroundActivities) {
8914 foreground = "A";
8915 } else if (r.foregroundServices) {
8916 foreground = "S";
8917 } else {
8918 foreground = " ";
8919 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008920 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07008921 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornce86ba82011-07-13 19:33:41 -07008922 N-i, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
8923 r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07008924 if (r.adjSource != null || r.adjTarget != null) {
8925 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008926 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008927 if (r.adjTarget instanceof ComponentName) {
8928 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
8929 } else if (r.adjTarget != null) {
8930 pw.print(r.adjTarget.toString());
8931 } else {
8932 pw.print("{null}");
8933 }
8934 pw.print("<=");
8935 if (r.adjSource instanceof ProcessRecord) {
8936 pw.print("Proc{");
8937 pw.print(((ProcessRecord)r.adjSource).toShortString());
8938 pw.println("}");
8939 } else if (r.adjSource != null) {
8940 pw.println(r.adjSource.toString());
8941 } else {
8942 pw.println("{null}");
8943 }
8944 }
8945 if (inclDetails) {
8946 pw.print(prefix);
8947 pw.print(" ");
8948 pw.print("oom: max="); pw.print(r.maxAdj);
8949 pw.print(" hidden="); pw.print(r.hiddenAdj);
8950 pw.print(" curRaw="); pw.print(r.curRawAdj);
8951 pw.print(" setRaw="); pw.print(r.setRawAdj);
8952 pw.print(" cur="); pw.print(r.curAdj);
8953 pw.print(" set="); pw.println(r.setAdj);
8954 pw.print(prefix);
8955 pw.print(" ");
8956 pw.print("keeping="); pw.print(r.keeping);
8957 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008958 pw.print(" empty="); pw.print(r.empty);
8959 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008960
8961 if (!r.keeping) {
8962 if (r.lastWakeTime != 0) {
8963 long wtime;
8964 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
8965 synchronized (stats) {
8966 wtime = stats.getProcessWakeTime(r.info.uid,
8967 r.pid, curRealtime);
8968 }
8969 long timeUsed = wtime - r.lastWakeTime;
8970 pw.print(prefix);
8971 pw.print(" ");
8972 pw.print("keep awake over ");
8973 TimeUtils.formatDuration(realtimeSince, pw);
8974 pw.print(" used ");
8975 TimeUtils.formatDuration(timeUsed, pw);
8976 pw.print(" (");
8977 pw.print((timeUsed*100)/realtimeSince);
8978 pw.println("%)");
8979 }
8980 if (r.lastCpuTime != 0) {
8981 long timeUsed = r.curCpuTime - r.lastCpuTime;
8982 pw.print(prefix);
8983 pw.print(" ");
8984 pw.print("run cpu over ");
8985 TimeUtils.formatDuration(uptimeSince, pw);
8986 pw.print(" used ");
8987 TimeUtils.formatDuration(timeUsed, pw);
8988 pw.print(" (");
8989 pw.print((timeUsed*100)/uptimeSince);
8990 pw.println("%)");
8991 }
8992 }
8993 }
8994 }
8995 }
8996
Dianne Hackbornb437e092011-08-05 17:50:29 -07008997 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008998 ArrayList<ProcessRecord> procs;
8999 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009000 if (args != null && args.length > start
9001 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009002 procs = new ArrayList<ProcessRecord>();
9003 int pid = -1;
9004 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009005 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009006 } catch (NumberFormatException e) {
9007
9008 }
9009 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9010 ProcessRecord proc = mLruProcesses.get(i);
9011 if (proc.pid == pid) {
9012 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009013 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009014 procs.add(proc);
9015 }
9016 }
9017 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009018 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009019 return null;
9020 }
9021 } else {
9022 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9023 }
9024 }
9025 return procs;
9026 }
9027
9028 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9029 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009030 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009031 if (procs == null) {
9032 return;
9033 }
9034
9035 long uptime = SystemClock.uptimeMillis();
9036 long realtime = SystemClock.elapsedRealtime();
9037 pw.println("Applications Graphics Acceleration Info:");
9038 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9039
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009040 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9041 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009042 if (r.thread != null) {
9043 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9044 pw.flush();
9045 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009046 TransferPipe tp = new TransferPipe();
9047 try {
9048 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9049 tp.go(fd);
9050 } finally {
9051 tp.kill();
9052 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009053 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009054 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009055 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009056 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009057 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009058 pw.flush();
9059 }
9060 }
9061 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009062 }
9063
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009064 final static class MemItem {
9065 final String label;
9066 final long pss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009067 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009068
9069 public MemItem(String _label, long _pss) {
9070 label = _label;
9071 pss = _pss;
9072 }
9073 }
9074
Dianne Hackbornb437e092011-08-05 17:50:29 -07009075 final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
9076 boolean sort) {
9077 if (sort) {
9078 Collections.sort(items, new Comparator<MemItem>() {
9079 @Override
9080 public int compare(MemItem lhs, MemItem rhs) {
9081 if (lhs.pss < rhs.pss) {
9082 return 1;
9083 } else if (lhs.pss > rhs.pss) {
9084 return -1;
9085 }
9086 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009087 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009088 });
9089 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009090
9091 for (int i=0; i<items.size(); i++) {
9092 MemItem mi = items.get(i);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009093 pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label);
9094 if (mi.subitems != null) {
9095 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9096 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009097 }
9098 }
9099
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009100 final void dumpApplicationMemoryUsage(FileDescriptor fd,
9101 PrintWriter pw, String prefix, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009102 boolean dumpAll = false;
9103
9104 int opti = 0;
9105 while (opti < args.length) {
9106 String opt = args[opti];
9107 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9108 break;
9109 }
9110 opti++;
9111 if ("-a".equals(opt)) {
9112 dumpAll = true;
9113 } else if ("-h".equals(opt)) {
9114 pw.println("meminfo dump options: [-a] [process]");
9115 pw.println(" -a: include all available information for each process.");
9116 pw.println("If [process] is specified it can be the name or ");
9117 pw.println("pid of a specific process to dump.");
9118 return;
9119 } else {
9120 pw.println("Unknown argument: " + opt + "; use -h for help");
9121 }
9122 }
9123
9124 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009125 if (procs == null) {
9126 return;
9127 }
9128
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009129 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009130 long uptime = SystemClock.uptimeMillis();
9131 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009132
9133 if (procs.size() == 1 || isCheckinRequest) {
9134 dumpAll = true;
9135 }
9136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009137 if (isCheckinRequest) {
9138 // short checkin version
9139 pw.println(uptime + "," + realtime);
9140 pw.flush();
9141 } else {
9142 pw.println("Applications Memory Usage (kB):");
9143 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9144 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009145
Dianne Hackbornb437e092011-08-05 17:50:29 -07009146 String[] innerArgs = new String[args.length-opti];
9147 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9148
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009149 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9150 long nativePss=0, dalvikPss=0, otherPss=0;
9151 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9152
Dianne Hackbornb437e092011-08-05 17:50:29 -07009153 final int[] oomAdj = new int[] {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009154 ProcessList.SYSTEM_ADJ, ProcessList.CORE_SERVER_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9155 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9156 ProcessList.BACKUP_APP_ADJ, ProcessList.SECONDARY_SERVER_ADJ, ProcessList.HOME_APP_ADJ, ProcessList.EMPTY_APP_ADJ
Dianne Hackbornb437e092011-08-05 17:50:29 -07009157 };
9158 final String[] oomLabel = new String[] {
9159 "System", "Persistent", "Foreground",
9160 "Visible", "Perceptible", "Heavy Weight",
9161 "Backup", "Services", "Home", "Background"
9162 };
9163 long oomPss[] = new long[oomLabel.length];
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009164 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009165
9166 long totalPss = 0;
9167
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009168 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9169 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009170 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009171 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9173 pw.flush();
9174 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009175 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009176 if (dumpAll) {
9177 try {
9178 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9179 } catch (RemoteException e) {
9180 if (!isCheckinRequest) {
9181 pw.println("Got RemoteException!");
9182 pw.flush();
9183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009184 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009185 } else {
9186 mi = new Debug.MemoryInfo();
9187 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009188 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009189
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009190 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009191 long myTotalPss = mi.getTotalPss();
9192 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009193 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
9194 myTotalPss);
9195 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009196
9197 nativePss += mi.nativePss;
9198 dalvikPss += mi.dalvikPss;
9199 otherPss += mi.otherPss;
9200 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9201 long mem = mi.getOtherPss(j);
9202 miscPss[j] += mem;
9203 otherPss -= mem;
9204 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009205
9206 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
9207 if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) {
9208 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009209 if (oomProcs[oomIndex] == null) {
9210 oomProcs[oomIndex] = new ArrayList<MemItem>();
9211 }
9212 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009213 break;
9214 }
9215 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009216 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009217 }
9218 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009219
9220 if (!isCheckinRequest && procs.size() > 1) {
9221 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9222
9223 catMems.add(new MemItem("Native", nativePss));
9224 catMems.add(new MemItem("Dalvik", dalvikPss));
9225 catMems.add(new MemItem("Unknown", otherPss));
9226 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9227 catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j]));
9228 }
9229
Dianne Hackbornb437e092011-08-05 17:50:29 -07009230 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9231 for (int j=0; j<oomPss.length; j++) {
9232 if (oomPss[j] != 0) {
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009233 MemItem item = new MemItem(oomLabel[j], oomPss[j]);
9234 item.subitems = oomProcs[j];
9235 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009236 }
9237 }
9238
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009239 pw.println();
9240 pw.println("Total PSS by process:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009241 dumpMemItems(pw, " ", procMems, true);
9242 pw.println();
9243 pw.println("Total PSS by OOM adjustment:");
9244 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009245 pw.println();
9246 pw.println("Total PSS by category:");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009247 dumpMemItems(pw, " ", catMems, true);
9248 pw.println();
9249 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009251 }
9252
9253 /**
9254 * Searches array of arguments for the specified string
9255 * @param args array of argument strings
9256 * @param value value to search for
9257 * @return true if the value is contained in the array
9258 */
9259 private static boolean scanArgs(String[] args, String value) {
9260 if (args != null) {
9261 for (String arg : args) {
9262 if (value.equals(arg)) {
9263 return true;
9264 }
9265 }
9266 }
9267 return false;
9268 }
9269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009270 private final void killServicesLocked(ProcessRecord app,
9271 boolean allowRestart) {
9272 // Report disconnected services.
9273 if (false) {
9274 // XXX we are letting the client link to the service for
9275 // death notifications.
9276 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009277 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009278 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009279 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009280 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009281 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009282 = r.connections.values().iterator();
9283 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009284 ArrayList<ConnectionRecord> cl = jt.next();
9285 for (int i=0; i<cl.size(); i++) {
9286 ConnectionRecord c = cl.get(i);
9287 if (c.binding.client != app) {
9288 try {
9289 //c.conn.connected(r.className, null);
9290 } catch (Exception e) {
9291 // todo: this should be asynchronous!
9292 Slog.w(TAG, "Exception thrown disconnected servce "
9293 + r.shortName
9294 + " from app " + app.processName, e);
9295 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009296 }
9297 }
9298 }
9299 }
9300 }
9301 }
9302 }
9303
9304 // Clean up any connections this application has to other services.
9305 if (app.connections.size() > 0) {
9306 Iterator<ConnectionRecord> it = app.connections.iterator();
9307 while (it.hasNext()) {
9308 ConnectionRecord r = it.next();
9309 removeConnectionLocked(r, app, null);
9310 }
9311 }
9312 app.connections.clear();
9313
9314 if (app.services.size() != 0) {
9315 // Any services running in the application need to be placed
9316 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009317 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009318 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009319 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009320 synchronized (sr.stats.getBatteryStats()) {
9321 sr.stats.stopLaunchedLocked();
9322 }
9323 sr.app = null;
9324 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009325 if (mStoppingServices.remove(sr)) {
9326 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9327 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009328
9329 boolean hasClients = sr.bindings.size() > 0;
9330 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009331 Iterator<IntentBindRecord> bindings
9332 = sr.bindings.values().iterator();
9333 while (bindings.hasNext()) {
9334 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009335 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009336 + ": shouldUnbind=" + b.hasBound);
9337 b.binder = null;
9338 b.requested = b.received = b.hasBound = false;
9339 }
9340 }
9341
Dianne Hackborn070783f2010-12-29 16:46:28 -08009342 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9343 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009344 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009345 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009346 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009347 sr.crashCount, sr.shortName, app.pid);
9348 bringDownServiceLocked(sr, true);
9349 } else if (!allowRestart) {
9350 bringDownServiceLocked(sr, true);
9351 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009352 boolean canceled = scheduleServiceRestartLocked(sr, true);
9353
9354 // Should the service remain running? Note that in the
9355 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009356 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009357 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
9358 if (sr.pendingStarts.size() == 0) {
9359 sr.startRequested = false;
9360 if (!hasClients) {
9361 // Whoops, no reason to restart!
9362 bringDownServiceLocked(sr, true);
9363 }
9364 }
9365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009366 }
9367 }
9368
9369 if (!allowRestart) {
9370 app.services.clear();
9371 }
9372 }
9373
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009374 // Make sure we have no more records on the stopping list.
9375 int i = mStoppingServices.size();
9376 while (i > 0) {
9377 i--;
9378 ServiceRecord sr = mStoppingServices.get(i);
9379 if (sr.app == app) {
9380 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009381 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009382 }
9383 }
9384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009385 app.executingServices.clear();
9386 }
9387
9388 private final void removeDyingProviderLocked(ProcessRecord proc,
9389 ContentProviderRecord cpr) {
9390 synchronized (cpr) {
9391 cpr.launchingApp = null;
9392 cpr.notifyAll();
9393 }
9394
9395 mProvidersByClass.remove(cpr.info.name);
9396 String names[] = cpr.info.authority.split(";");
9397 for (int j = 0; j < names.length; j++) {
9398 mProvidersByName.remove(names[j]);
9399 }
9400
9401 Iterator<ProcessRecord> cit = cpr.clients.iterator();
9402 while (cit.hasNext()) {
9403 ProcessRecord capp = cit.next();
9404 if (!capp.persistent && capp.thread != null
9405 && capp.pid != 0
9406 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07009407 Slog.i(TAG, "Kill " + capp.processName
9408 + " (pid " + capp.pid + "): provider " + cpr.info.name
9409 + " in dying process " + proc.processName);
9410 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
9411 capp.processName, capp.setAdj, "dying provider " + proc.processName);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009412 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009413 }
9414 }
9415
9416 mLaunchingProviders.remove(cpr);
9417 }
9418
9419 /**
9420 * Main code for cleaning up a process when it has gone away. This is
9421 * called both as a result of the process dying, or directly when stopping
9422 * a process when running in single process mode.
9423 */
9424 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009425 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009426 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009427 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009428 }
9429
Dianne Hackborn36124872009-10-08 16:22:03 -07009430 mProcessesToGc.remove(app);
9431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009432 // Dismiss any open dialogs.
9433 if (app.crashDialog != null) {
9434 app.crashDialog.dismiss();
9435 app.crashDialog = null;
9436 }
9437 if (app.anrDialog != null) {
9438 app.anrDialog.dismiss();
9439 app.anrDialog = null;
9440 }
9441 if (app.waitDialog != null) {
9442 app.waitDialog.dismiss();
9443 app.waitDialog = null;
9444 }
9445
9446 app.crashing = false;
9447 app.notResponding = false;
9448
9449 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07009450 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009451 app.thread = null;
9452 app.forcingToForeground = null;
9453 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009454 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07009455 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009456 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009457
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009458 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009459
9460 boolean restart = false;
9461
9462 int NL = mLaunchingProviders.size();
9463
9464 // Remove published content providers.
9465 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009466 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009467 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009468 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009469 cpr.provider = null;
9470 cpr.app = null;
9471
9472 // See if someone is waiting for this provider... in which
9473 // case we don't remove it, but just let it restart.
9474 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07009475 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009476 for (; i<NL; i++) {
9477 if (mLaunchingProviders.get(i) == cpr) {
9478 restart = true;
9479 break;
9480 }
9481 }
9482 } else {
9483 i = NL;
9484 }
9485
9486 if (i >= NL) {
9487 removeDyingProviderLocked(app, cpr);
9488 NL = mLaunchingProviders.size();
9489 }
9490 }
9491 app.pubProviders.clear();
9492 }
9493
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009494 // Take care of any launching providers waiting for this process.
9495 if (checkAppInLaunchingProvidersLocked(app, false)) {
9496 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009498
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009499 // Unregister from connected content providers.
9500 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07009501 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009502 while (it.hasNext()) {
9503 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
9504 cpr.clients.remove(app);
9505 }
9506 app.conProviders.clear();
9507 }
9508
Dianne Hackbornde42bb62009-08-05 12:26:15 -07009509 // At this point there may be remaining entries in mLaunchingProviders
9510 // where we were the only one waiting, so they are no longer of use.
9511 // Look for these and clean up if found.
9512 // XXX Commented out for now. Trying to figure out a way to reproduce
9513 // the actual situation to identify what is actually going on.
9514 if (false) {
9515 for (int i=0; i<NL; i++) {
9516 ContentProviderRecord cpr = (ContentProviderRecord)
9517 mLaunchingProviders.get(i);
9518 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
9519 synchronized (cpr) {
9520 cpr.launchingApp = null;
9521 cpr.notifyAll();
9522 }
9523 }
9524 }
9525 }
9526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009527 skipCurrentReceiverLocked(app);
9528
9529 // Unregister any receivers.
9530 if (app.receivers.size() > 0) {
9531 Iterator<ReceiverList> it = app.receivers.iterator();
9532 while (it.hasNext()) {
9533 removeReceiverLocked(it.next());
9534 }
9535 app.receivers.clear();
9536 }
9537
Christopher Tate181fafa2009-05-14 11:12:14 -07009538 // If the app is undergoing backup, tell the backup manager about it
9539 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009540 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -07009541 try {
9542 IBackupManager bm = IBackupManager.Stub.asInterface(
9543 ServiceManager.getService(Context.BACKUP_SERVICE));
9544 bm.agentDisconnected(app.info.packageName);
9545 } catch (RemoteException e) {
9546 // can't happen; backup manager is local
9547 }
9548 }
9549
Jeff Sharkey287bd832011-05-28 19:36:26 -07009550 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009552 // If the caller is restarting this app, then leave it in its
9553 // current lists and let the caller take care of it.
9554 if (restarting) {
9555 return;
9556 }
9557
9558 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009559 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009560 "Removing non-persistent process during cleanup: " + app);
9561 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07009562 if (mHeavyWeightProcess == app) {
9563 mHeavyWeightProcess = null;
9564 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
9565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009566 } else if (!app.removed) {
9567 // This app is persistent, so we need to keep its record around.
9568 // If it is not already on the pending app list, add it there
9569 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009570 if (mPersistentStartingProcesses.indexOf(app) < 0) {
9571 mPersistentStartingProcesses.add(app);
9572 restart = true;
9573 }
9574 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009575 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
9576 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009577 mProcessesOnHold.remove(app);
9578
The Android Open Source Project4df24232009-03-05 14:34:35 -08009579 if (app == mHomeProcess) {
9580 mHomeProcess = null;
9581 }
9582
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009583 if (restart) {
9584 // We have components that still need to be running in the
9585 // process, so re-launch it.
9586 mProcessNames.put(app.processName, app.info.uid, app);
9587 startProcessLocked(app, "restart", app.processName);
9588 } else if (app.pid > 0 && app.pid != MY_PID) {
9589 // Goodbye!
9590 synchronized (mPidsSelfLocked) {
9591 mPidsSelfLocked.remove(app.pid);
9592 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
9593 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009594 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009595 }
9596 }
9597
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009598 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
9599 // Look through the content providers we are waiting to have launched,
9600 // and if any run in this process then either schedule a restart of
9601 // the process or kill the client waiting for it if this process has
9602 // gone bad.
9603 int NL = mLaunchingProviders.size();
9604 boolean restart = false;
9605 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009606 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08009607 if (cpr.launchingApp == app) {
9608 if (!alwaysBad && !app.bad) {
9609 restart = true;
9610 } else {
9611 removeDyingProviderLocked(app, cpr);
9612 NL = mLaunchingProviders.size();
9613 }
9614 }
9615 }
9616 return restart;
9617 }
9618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009619 // =========================================================
9620 // SERVICES
9621 // =========================================================
9622
9623 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
9624 ActivityManager.RunningServiceInfo info =
9625 new ActivityManager.RunningServiceInfo();
9626 info.service = r.name;
9627 if (r.app != null) {
9628 info.pid = r.app.pid;
9629 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009630 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009631 info.process = r.processName;
9632 info.foreground = r.isForeground;
9633 info.activeSince = r.createTime;
9634 info.started = r.startRequested;
9635 info.clientCount = r.connections.size();
9636 info.crashCount = r.crashCount;
9637 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009638 if (r.isForeground) {
9639 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
9640 }
9641 if (r.startRequested) {
9642 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
9643 }
Dan Egnor42471dd2010-01-07 17:25:22 -08009644 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -07009645 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
9646 }
9647 if (r.app != null && r.app.persistent) {
9648 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
9649 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009650
9651 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
9652 for (int i=0; i<connl.size(); i++) {
9653 ConnectionRecord conn = connl.get(i);
9654 if (conn.clientLabel != 0) {
9655 info.clientPackage = conn.binding.client.info.packageName;
9656 info.clientLabel = conn.clientLabel;
9657 return info;
9658 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009659 }
9660 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 return info;
9662 }
9663
9664 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
9665 int flags) {
9666 synchronized (this) {
9667 ArrayList<ActivityManager.RunningServiceInfo> res
9668 = new ArrayList<ActivityManager.RunningServiceInfo>();
9669
9670 if (mServices.size() > 0) {
9671 Iterator<ServiceRecord> it = mServices.values().iterator();
9672 while (it.hasNext() && res.size() < maxNum) {
9673 res.add(makeRunningServiceInfoLocked(it.next()));
9674 }
9675 }
9676
9677 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
9678 ServiceRecord r = mRestartingServices.get(i);
9679 ActivityManager.RunningServiceInfo info =
9680 makeRunningServiceInfoLocked(r);
9681 info.restarting = r.nextRestartTime;
9682 res.add(info);
9683 }
9684
9685 return res;
9686 }
9687 }
9688
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009689 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
9690 synchronized (this) {
9691 ServiceRecord r = mServices.get(name);
9692 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009693 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
9694 for (int i=0; i<conn.size(); i++) {
9695 if (conn.get(i).clientIntent != null) {
9696 return conn.get(i).clientIntent;
9697 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07009698 }
9699 }
9700 }
9701 }
9702 return null;
9703 }
9704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009705 private final ServiceRecord findServiceLocked(ComponentName name,
9706 IBinder token) {
9707 ServiceRecord r = mServices.get(name);
9708 return r == token ? r : null;
9709 }
9710
9711 private final class ServiceLookupResult {
9712 final ServiceRecord record;
9713 final String permission;
9714
9715 ServiceLookupResult(ServiceRecord _record, String _permission) {
9716 record = _record;
9717 permission = _permission;
9718 }
9719 };
9720
9721 private ServiceLookupResult findServiceLocked(Intent service,
9722 String resolvedType) {
9723 ServiceRecord r = null;
9724 if (service.getComponent() != null) {
9725 r = mServices.get(service.getComponent());
9726 }
9727 if (r == null) {
9728 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9729 r = mServicesByIntent.get(filter);
9730 }
9731
9732 if (r == null) {
9733 try {
9734 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009735 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009736 service, resolvedType, 0);
9737 ServiceInfo sInfo =
9738 rInfo != null ? rInfo.serviceInfo : null;
9739 if (sInfo == null) {
9740 return null;
9741 }
9742
9743 ComponentName name = new ComponentName(
9744 sInfo.applicationInfo.packageName, sInfo.name);
9745 r = mServices.get(name);
9746 } catch (RemoteException ex) {
9747 // pm is in same process, this will never happen.
9748 }
9749 }
9750 if (r != null) {
9751 int callingPid = Binder.getCallingPid();
9752 int callingUid = Binder.getCallingUid();
9753 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009754 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009755 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009756 if (!r.exported) {
9757 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9758 + " from pid=" + callingPid
9759 + ", uid=" + callingUid
9760 + " that is not exported from uid " + r.appInfo.uid);
9761 return new ServiceLookupResult(null, "not exported from uid "
9762 + r.appInfo.uid);
9763 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009764 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 + " from pid=" + callingPid
9766 + ", uid=" + callingUid
9767 + " requires " + r.permission);
9768 return new ServiceLookupResult(null, r.permission);
9769 }
9770 return new ServiceLookupResult(r, null);
9771 }
9772 return null;
9773 }
9774
9775 private class ServiceRestarter implements Runnable {
9776 private ServiceRecord mService;
9777
9778 void setService(ServiceRecord service) {
9779 mService = service;
9780 }
9781
9782 public void run() {
9783 synchronized(ActivityManagerService.this) {
9784 performServiceRestartLocked(mService);
9785 }
9786 }
9787 }
9788
9789 private ServiceLookupResult retrieveServiceLocked(Intent service,
9790 String resolvedType, int callingPid, int callingUid) {
9791 ServiceRecord r = null;
9792 if (service.getComponent() != null) {
9793 r = mServices.get(service.getComponent());
9794 }
9795 Intent.FilterComparison filter = new Intent.FilterComparison(service);
9796 r = mServicesByIntent.get(filter);
9797 if (r == null) {
9798 try {
9799 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07009800 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -07009801 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 ServiceInfo sInfo =
9803 rInfo != null ? rInfo.serviceInfo : null;
9804 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009805 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009806 ": not found");
9807 return null;
9808 }
9809
9810 ComponentName name = new ComponentName(
9811 sInfo.applicationInfo.packageName, sInfo.name);
9812 r = mServices.get(name);
9813 if (r == null) {
9814 filter = new Intent.FilterComparison(service.cloneFilter());
9815 ServiceRestarter res = new ServiceRestarter();
9816 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
9817 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
9818 synchronized (stats) {
9819 ss = stats.getServiceStatsLocked(
9820 sInfo.applicationInfo.uid, sInfo.packageName,
9821 sInfo.name);
9822 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -08009823 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009824 res.setService(r);
9825 mServices.put(name, r);
9826 mServicesByIntent.put(filter, r);
9827
9828 // Make sure this component isn't in the pending list.
9829 int N = mPendingServices.size();
9830 for (int i=0; i<N; i++) {
9831 ServiceRecord pr = mPendingServices.get(i);
9832 if (pr.name.equals(name)) {
9833 mPendingServices.remove(i);
9834 i--;
9835 N--;
9836 }
9837 }
9838 }
9839 } catch (RemoteException ex) {
9840 // pm is in same process, this will never happen.
9841 }
9842 }
9843 if (r != null) {
9844 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009845 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009846 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009847 if (!r.exported) {
9848 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
9849 + " from pid=" + callingPid
9850 + ", uid=" + callingUid
9851 + " that is not exported from uid " + r.appInfo.uid);
9852 return new ServiceLookupResult(null, "not exported from uid "
9853 + r.appInfo.uid);
9854 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08009855 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08009856 + " from pid=" + callingPid
9857 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009858 + " requires " + r.permission);
9859 return new ServiceLookupResult(null, r.permission);
9860 }
9861 return new ServiceLookupResult(r, null);
9862 }
9863 return null;
9864 }
9865
Dianne Hackborn287952c2010-09-22 22:34:31 -07009866 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
9867 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
9868 + why + " of " + r + " in app " + r.app);
9869 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
9870 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009871 long now = SystemClock.uptimeMillis();
9872 if (r.executeNesting == 0 && r.app != null) {
9873 if (r.app.executingServices.size() == 0) {
9874 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
9875 msg.obj = r.app;
9876 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
9877 }
9878 r.app.executingServices.add(r);
9879 }
9880 r.executeNesting++;
9881 r.executingStart = now;
9882 }
9883
9884 private final void sendServiceArgsLocked(ServiceRecord r,
9885 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009886 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009887 if (N == 0) {
9888 return;
9889 }
9890
Dianne Hackborn39792d22010-08-19 18:01:52 -07009891 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009892 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009893 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009894 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
9895 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009896 if (si.intent == null && N > 1) {
9897 // If somehow we got a dummy null intent in the middle,
9898 // then skip it. DO NOT skip a null intent when it is
9899 // the only one in the list -- this is to support the
9900 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009901 continue;
9902 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07009903 si.deliveredTime = SystemClock.uptimeMillis();
9904 r.deliveredStarts.add(si);
9905 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -08009906 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07009907 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -07009908 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -07009909 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009910 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009911 if (!oomAdjusted) {
9912 oomAdjusted = true;
9913 updateOomAdjLocked(r.app);
9914 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009915 int flags = 0;
9916 if (si.deliveryCount > 0) {
9917 flags |= Service.START_FLAG_RETRY;
9918 }
9919 if (si.doneExecutingCount > 0) {
9920 flags |= Service.START_FLAG_REDELIVERY;
9921 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07009922 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009923 } catch (RemoteException e) {
9924 // Remote process gone... we'll let the normal cleanup take
9925 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009926 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009927 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009928 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009929 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009930 break;
9931 }
9932 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009933 }
9934
9935 private final boolean requestServiceBindingLocked(ServiceRecord r,
9936 IntentBindRecord i, boolean rebind) {
9937 if (r.app == null || r.app.thread == null) {
9938 // If service is not currently running, can't yet bind.
9939 return false;
9940 }
9941 if ((!i.requested || rebind) && i.apps.size() > 0) {
9942 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009943 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009944 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
9945 if (!rebind) {
9946 i.requested = true;
9947 }
9948 i.hasBound = true;
9949 i.doRebind = false;
9950 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009951 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009952 return false;
9953 }
9954 }
9955 return true;
9956 }
9957
9958 private final void requestServiceBindingsLocked(ServiceRecord r) {
9959 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
9960 while (bindings.hasNext()) {
9961 IntentBindRecord i = bindings.next();
9962 if (!requestServiceBindingLocked(r, i, false)) {
9963 break;
9964 }
9965 }
9966 }
9967
9968 private final void realStartServiceLocked(ServiceRecord r,
9969 ProcessRecord app) throws RemoteException {
9970 if (app.thread == null) {
9971 throw new RemoteException();
9972 }
9973
9974 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -07009975 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009976
9977 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009978 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -08009979 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009980
9981 boolean created = false;
9982 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009983 mStringBuilder.setLength(0);
9984 r.intent.getIntent().toShortString(mStringBuilder, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009985 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009986 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -07009987 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009988 synchronized (r.stats.getBatteryStats()) {
9989 r.stats.startLaunchedLocked();
9990 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07009991 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04009992 app.thread.scheduleCreateService(r, r.serviceInfo,
9993 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -07009994 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009995 created = true;
9996 } finally {
9997 if (!created) {
9998 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009999 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010000 }
10001 }
10002
10003 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010004
10005 // If the service is in the started state, and there are no
10006 // pending arguments, then fake up one so its onStartCommand() will
10007 // be called.
10008 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010009 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10010 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010011 }
10012
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010013 sendServiceArgsLocked(r, true);
10014 }
10015
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010016 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10017 boolean allowCancel) {
10018 boolean canceled = false;
10019
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010020 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010021 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010022 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010023
Dianne Hackborn070783f2010-12-29 16:46:28 -080010024 if ((r.serviceInfo.applicationInfo.flags
10025 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10026 minDuration /= 4;
10027 }
10028
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010029 // Any delivered but not yet finished starts should be put back
10030 // on the pending list.
10031 final int N = r.deliveredStarts.size();
10032 if (N > 0) {
10033 for (int i=N-1; i>=0; i--) {
10034 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010035 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010036 if (si.intent == null) {
10037 // We'll generate this again if needed.
10038 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10039 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10040 r.pendingStarts.add(0, si);
10041 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10042 dur *= 2;
10043 if (minDuration < dur) minDuration = dur;
10044 if (resetTime < dur) resetTime = dur;
10045 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010046 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010047 + r.name);
10048 canceled = true;
10049 }
10050 }
10051 r.deliveredStarts.clear();
10052 }
10053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010054 r.totalRestartCount++;
10055 if (r.restartDelay == 0) {
10056 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010057 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010058 } else {
10059 // If it has been a "reasonably long time" since the service
10060 // was started, then reset our restart duration back to
10061 // the beginning, so we don't infinitely increase the duration
10062 // on a service that just occasionally gets killed (which is
10063 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010064 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010065 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010066 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010067 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010068 if ((r.serviceInfo.applicationInfo.flags
10069 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10070 // Services in peristent processes will restart much more
10071 // quickly, since they are pretty important. (Think SystemUI).
10072 r.restartDelay += minDuration/2;
10073 } else {
10074 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10075 if (r.restartDelay < minDuration) {
10076 r.restartDelay = minDuration;
10077 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010078 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010079 }
10080 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010081
10082 r.nextRestartTime = now + r.restartDelay;
10083
10084 // Make sure that we don't end up restarting a bunch of services
10085 // all at the same time.
10086 boolean repeat;
10087 do {
10088 repeat = false;
10089 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10090 ServiceRecord r2 = mRestartingServices.get(i);
10091 if (r2 != r && r.nextRestartTime
10092 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10093 && r.nextRestartTime
10094 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10095 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10096 r.restartDelay = r.nextRestartTime - now;
10097 repeat = true;
10098 break;
10099 }
10100 }
10101 } while (repeat);
10102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010103 if (!mRestartingServices.contains(r)) {
10104 mRestartingServices.add(r);
10105 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010106
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010107 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010109 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010110 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010111 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010112 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010113 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010114 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010115 r.shortName, r.restartDelay);
10116
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010117 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010118 }
10119
10120 final void performServiceRestartLocked(ServiceRecord r) {
10121 if (!mRestartingServices.contains(r)) {
10122 return;
10123 }
10124 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10125 }
10126
10127 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10128 if (r.restartDelay == 0) {
10129 return false;
10130 }
10131 r.resetRestartCounter();
10132 mRestartingServices.remove(r);
10133 mHandler.removeCallbacks(r.restarter);
10134 return true;
10135 }
10136
10137 private final boolean bringUpServiceLocked(ServiceRecord r,
10138 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010139 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010140 //r.dump(" ");
10141
Dianne Hackborn36124872009-10-08 16:22:03 -070010142 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010143 sendServiceArgsLocked(r, false);
10144 return true;
10145 }
10146
10147 if (!whileRestarting && r.restartDelay > 0) {
10148 // If waiting for a restart, then do nothing.
10149 return true;
10150 }
10151
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010152 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010153
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010154 // We are now bringing the service up, so no longer in the
10155 // restarting state.
10156 mRestartingServices.remove(r);
10157
Dianne Hackborne7f97212011-02-24 14:40:20 -080010158 // Service is now being launched, its package can't be stopped.
10159 try {
10160 AppGlobals.getPackageManager().setPackageStoppedState(
10161 r.packageName, false);
10162 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010163 } catch (IllegalArgumentException e) {
10164 Slog.w(TAG, "Failed trying to unstop package "
10165 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010166 }
10167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010168 final String appName = r.processName;
10169 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10170 if (app != null && app.thread != null) {
10171 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010172 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010173 realStartServiceLocked(r, app);
10174 return true;
10175 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010176 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010177 }
10178
10179 // If a dead object exception was thrown -- fall through to
10180 // restart the application.
10181 }
10182
Dianne Hackborn36124872009-10-08 16:22:03 -070010183 // Not running -- get it started, and enqueue this service record
10184 // to be executed when the app comes up.
10185 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10186 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010187 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010188 + r.appInfo.packageName + "/"
10189 + r.appInfo.uid + " for service "
10190 + r.intent.getIntent() + ": process is bad");
10191 bringDownServiceLocked(r, true);
10192 return false;
10193 }
10194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010195 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010196 mPendingServices.add(r);
10197 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010198
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010199 return true;
10200 }
10201
10202 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010203 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010204 //r.dump(" ");
10205
10206 // Does it still need to run?
10207 if (!force && r.startRequested) {
10208 return;
10209 }
10210 if (r.connections.size() > 0) {
10211 if (!force) {
10212 // XXX should probably keep a count of the number of auto-create
10213 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010214 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010215 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010216 ArrayList<ConnectionRecord> cr = it.next();
10217 for (int i=0; i<cr.size(); i++) {
10218 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10219 return;
10220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010221 }
10222 }
10223 }
10224
10225 // Report to all of the connections that the service is no longer
10226 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010227 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010228 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010229 ArrayList<ConnectionRecord> c = it.next();
10230 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010231 ConnectionRecord cr = c.get(i);
10232 // There is still a connection to the service that is
10233 // being brought down. Mark it as dead.
10234 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010235 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010236 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010237 } catch (Exception e) {
10238 Slog.w(TAG, "Failure disconnecting service " + r.name +
10239 " to connection " + c.get(i).conn.asBinder() +
10240 " (in " + c.get(i).binding.client.processName + ")", e);
10241 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010242 }
10243 }
10244 }
10245
10246 // Tell the service that it has been unbound.
10247 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10248 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10249 while (it.hasNext()) {
10250 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010251 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010252 + ": hasBound=" + ibr.hasBound);
10253 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10254 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010255 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010256 updateOomAdjLocked(r.app);
10257 ibr.hasBound = false;
10258 r.app.thread.scheduleUnbindService(r,
10259 ibr.intent.getIntent());
10260 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010261 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010262 + r.shortName, e);
10263 serviceDoneExecutingLocked(r, true);
10264 }
10265 }
10266 }
10267 }
10268
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010269 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010270 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010271 System.identityHashCode(r), r.shortName,
10272 (r.app != null) ? r.app.pid : -1);
10273
10274 mServices.remove(r.name);
10275 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010276 r.totalRestartCount = 0;
10277 unscheduleServiceRestartLocked(r);
10278
10279 // Also make sure it is not on the pending list.
10280 int N = mPendingServices.size();
10281 for (int i=0; i<N; i++) {
10282 if (mPendingServices.get(i) == r) {
10283 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010284 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010285 i--;
10286 N--;
10287 }
10288 }
10289
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010290 r.cancelNotification();
10291 r.isForeground = false;
10292 r.foregroundId = 0;
10293 r.foregroundNoti = null;
10294
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010295 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010296 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010297 r.pendingStarts.clear();
10298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010299 if (r.app != null) {
10300 synchronized (r.stats.getBatteryStats()) {
10301 r.stats.stopLaunchedLocked();
10302 }
10303 r.app.services.remove(r);
10304 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010305 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010306 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010307 mStoppingServices.add(r);
10308 updateOomAdjLocked(r.app);
10309 r.app.thread.scheduleStopService(r);
10310 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010311 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010312 + r.shortName, e);
10313 serviceDoneExecutingLocked(r, true);
10314 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010315 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010316 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010317 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010318 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010319 }
10320 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010321 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010322 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010323 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010324
10325 if (r.bindings.size() > 0) {
10326 r.bindings.clear();
10327 }
10328
10329 if (r.restarter instanceof ServiceRestarter) {
10330 ((ServiceRestarter)r.restarter).setService(null);
10331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010332 }
10333
10334 ComponentName startServiceLocked(IApplicationThread caller,
10335 Intent service, String resolvedType,
10336 int callingPid, int callingUid) {
10337 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010338 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010339 + " type=" + resolvedType + " args=" + service.getExtras());
10340
10341 if (caller != null) {
10342 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10343 if (callerApp == null) {
10344 throw new SecurityException(
10345 "Unable to find app for caller " + caller
10346 + " (pid=" + Binder.getCallingPid()
10347 + ") when starting service " + service);
10348 }
10349 }
10350
10351 ServiceLookupResult res =
10352 retrieveServiceLocked(service, resolvedType,
10353 callingPid, callingUid);
10354 if (res == null) {
10355 return null;
10356 }
10357 if (res.record == null) {
10358 return new ComponentName("!", res.permission != null
10359 ? res.permission : "private to package");
10360 }
10361 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070010362 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
10363 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010364 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010365 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010366 }
10367 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010368 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010369 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070010370 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010371 r.lastActivity = SystemClock.uptimeMillis();
10372 synchronized (r.stats.getBatteryStats()) {
10373 r.stats.startRunningLocked();
10374 }
10375 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
10376 return new ComponentName("!", "Service process is bad");
10377 }
10378 return r.name;
10379 }
10380 }
10381
10382 public ComponentName startService(IApplicationThread caller, Intent service,
10383 String resolvedType) {
10384 // Refuse possible leaked file descriptors
10385 if (service != null && service.hasFileDescriptors() == true) {
10386 throw new IllegalArgumentException("File descriptors passed in Intent");
10387 }
10388
10389 synchronized(this) {
10390 final int callingPid = Binder.getCallingPid();
10391 final int callingUid = Binder.getCallingUid();
10392 final long origId = Binder.clearCallingIdentity();
10393 ComponentName res = startServiceLocked(caller, service,
10394 resolvedType, callingPid, callingUid);
10395 Binder.restoreCallingIdentity(origId);
10396 return res;
10397 }
10398 }
10399
10400 ComponentName startServiceInPackage(int uid,
10401 Intent service, String resolvedType) {
10402 synchronized(this) {
10403 final long origId = Binder.clearCallingIdentity();
10404 ComponentName res = startServiceLocked(null, service,
10405 resolvedType, -1, uid);
10406 Binder.restoreCallingIdentity(origId);
10407 return res;
10408 }
10409 }
10410
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010411 private void stopServiceLocked(ServiceRecord service) {
10412 synchronized (service.stats.getBatteryStats()) {
10413 service.stats.stopRunningLocked();
10414 }
10415 service.startRequested = false;
10416 service.callStart = false;
10417 bringDownServiceLocked(service, false);
10418 }
10419
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010420 public int stopService(IApplicationThread caller, Intent service,
10421 String resolvedType) {
10422 // Refuse possible leaked file descriptors
10423 if (service != null && service.hasFileDescriptors() == true) {
10424 throw new IllegalArgumentException("File descriptors passed in Intent");
10425 }
10426
10427 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010428 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010429 + " type=" + resolvedType);
10430
10431 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10432 if (caller != null && callerApp == null) {
10433 throw new SecurityException(
10434 "Unable to find app for caller " + caller
10435 + " (pid=" + Binder.getCallingPid()
10436 + ") when stopping service " + service);
10437 }
10438
10439 // If this service is active, make sure it is stopped.
10440 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10441 if (r != null) {
10442 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010443 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010444 try {
10445 stopServiceLocked(r.record);
10446 } finally {
10447 Binder.restoreCallingIdentity(origId);
10448 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010449 return 1;
10450 }
10451 return -1;
10452 }
10453 }
10454
10455 return 0;
10456 }
10457
10458 public IBinder peekService(Intent service, String resolvedType) {
10459 // Refuse possible leaked file descriptors
10460 if (service != null && service.hasFileDescriptors() == true) {
10461 throw new IllegalArgumentException("File descriptors passed in Intent");
10462 }
10463
10464 IBinder ret = null;
10465
10466 synchronized(this) {
10467 ServiceLookupResult r = findServiceLocked(service, resolvedType);
10468
10469 if (r != null) {
10470 // r.record is null if findServiceLocked() failed the caller permission check
10471 if (r.record == null) {
10472 throw new SecurityException(
10473 "Permission Denial: Accessing service " + r.record.name
10474 + " from pid=" + Binder.getCallingPid()
10475 + ", uid=" + Binder.getCallingUid()
10476 + " requires " + r.permission);
10477 }
10478 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
10479 if (ib != null) {
10480 ret = ib.binder;
10481 }
10482 }
10483 }
10484
10485 return ret;
10486 }
10487
10488 public boolean stopServiceToken(ComponentName className, IBinder token,
10489 int startId) {
10490 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010491 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010492 + " " + token + " startId=" + startId);
10493 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010494 if (r != null) {
10495 if (startId >= 0) {
10496 // Asked to only stop if done with all work. Note that
10497 // to avoid leaks, we will take this as dropping all
10498 // start items up to and including this one.
10499 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10500 if (si != null) {
10501 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010502 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
10503 cur.removeUriPermissionsLocked();
10504 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010505 break;
10506 }
10507 }
10508 }
10509
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010510 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010511 return false;
10512 }
10513
10514 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010515 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010516 + " is last, but have " + r.deliveredStarts.size()
10517 + " remaining args");
10518 }
10519 }
10520
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010521 synchronized (r.stats.getBatteryStats()) {
10522 r.stats.stopRunningLocked();
10523 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010524 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010525 }
10526 final long origId = Binder.clearCallingIdentity();
10527 bringDownServiceLocked(r, false);
10528 Binder.restoreCallingIdentity(origId);
10529 return true;
10530 }
10531 }
10532 return false;
10533 }
10534
10535 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010536 int id, Notification notification, boolean removeNotification) {
10537 final long origId = Binder.clearCallingIdentity();
10538 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010539 synchronized(this) {
10540 ServiceRecord r = findServiceLocked(className, token);
10541 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010542 if (id != 0) {
10543 if (notification == null) {
10544 throw new IllegalArgumentException("null notification");
10545 }
10546 if (r.foregroundId != id) {
10547 r.cancelNotification();
10548 r.foregroundId = id;
10549 }
10550 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
10551 r.foregroundNoti = notification;
10552 r.isForeground = true;
10553 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010554 if (r.app != null) {
10555 updateServiceForegroundLocked(r.app, true);
10556 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010557 } else {
10558 if (r.isForeground) {
10559 r.isForeground = false;
10560 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010561 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010562 updateServiceForegroundLocked(r.app, true);
10563 }
10564 }
10565 if (removeNotification) {
10566 r.cancelNotification();
10567 r.foregroundId = 0;
10568 r.foregroundNoti = null;
10569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010570 }
10571 }
10572 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010573 } finally {
10574 Binder.restoreCallingIdentity(origId);
10575 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010576 }
10577
10578 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
10579 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010580 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010581 if (sr.isForeground) {
10582 anyForeground = true;
10583 break;
10584 }
10585 }
10586 if (anyForeground != proc.foregroundServices) {
10587 proc.foregroundServices = anyForeground;
10588 if (oomAdj) {
10589 updateOomAdjLocked();
10590 }
10591 }
10592 }
10593
10594 public int bindService(IApplicationThread caller, IBinder token,
10595 Intent service, String resolvedType,
10596 IServiceConnection connection, int flags) {
10597 // Refuse possible leaked file descriptors
10598 if (service != null && service.hasFileDescriptors() == true) {
10599 throw new IllegalArgumentException("File descriptors passed in Intent");
10600 }
10601
10602 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010603 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010604 + " type=" + resolvedType + " conn=" + connection.asBinder()
10605 + " flags=0x" + Integer.toHexString(flags));
10606 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10607 if (callerApp == null) {
10608 throw new SecurityException(
10609 "Unable to find app for caller " + caller
10610 + " (pid=" + Binder.getCallingPid()
10611 + ") when binding service " + service);
10612 }
10613
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010614 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010615 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010616 activity = mMainStack.isInStackLocked(token);
10617 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010618 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010619 return 0;
10620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010621 }
10622
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010623 int clientLabel = 0;
10624 PendingIntent clientIntent = null;
10625
10626 if (callerApp.info.uid == Process.SYSTEM_UID) {
10627 // Hacky kind of thing -- allow system stuff to tell us
10628 // what they are, so we can report this elsewhere for
10629 // others to know why certain services are running.
10630 try {
10631 clientIntent = (PendingIntent)service.getParcelableExtra(
10632 Intent.EXTRA_CLIENT_INTENT);
10633 } catch (RuntimeException e) {
10634 }
10635 if (clientIntent != null) {
10636 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
10637 if (clientLabel != 0) {
10638 // There are no useful extras in the intent, trash them.
10639 // System code calling with this stuff just needs to know
10640 // this will happen.
10641 service = service.cloneFilter();
10642 }
10643 }
10644 }
10645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010646 ServiceLookupResult res =
10647 retrieveServiceLocked(service, resolvedType,
10648 Binder.getCallingPid(), Binder.getCallingUid());
10649 if (res == null) {
10650 return 0;
10651 }
10652 if (res.record == null) {
10653 return -1;
10654 }
10655 ServiceRecord s = res.record;
10656
10657 final long origId = Binder.clearCallingIdentity();
10658
10659 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010660 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010661 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010662 }
10663
10664 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
10665 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010666 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010667
10668 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010669 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10670 if (clist == null) {
10671 clist = new ArrayList<ConnectionRecord>();
10672 s.connections.put(binder, clist);
10673 }
10674 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 b.connections.add(c);
10676 if (activity != null) {
10677 if (activity.connections == null) {
10678 activity.connections = new HashSet<ConnectionRecord>();
10679 }
10680 activity.connections.add(c);
10681 }
10682 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010683 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10684 b.client.hasAboveClient = true;
10685 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010686 clist = mServiceConnections.get(binder);
10687 if (clist == null) {
10688 clist = new ArrayList<ConnectionRecord>();
10689 mServiceConnections.put(binder, clist);
10690 }
10691 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010692
10693 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
10694 s.lastActivity = SystemClock.uptimeMillis();
10695 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
10696 return 0;
10697 }
10698 }
10699
10700 if (s.app != null) {
10701 // This could have made the service more important.
10702 updateOomAdjLocked(s.app);
10703 }
10704
Joe Onorato8a9b2202010-02-26 18:56:32 -080010705 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010706 + ": received=" + b.intent.received
10707 + " apps=" + b.intent.apps.size()
10708 + " doRebind=" + b.intent.doRebind);
10709
10710 if (s.app != null && b.intent.received) {
10711 // Service is already running, so we can immediately
10712 // publish the connection.
10713 try {
10714 c.conn.connected(s.name, b.intent.binder);
10715 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010716 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010717 + " to connection " + c.conn.asBinder()
10718 + " (in " + c.binding.client.processName + ")", e);
10719 }
10720
10721 // If this is the first app connected back to this binding,
10722 // and the service had previously asked to be told when
10723 // rebound, then do so.
10724 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
10725 requestServiceBindingLocked(s, b.intent, true);
10726 }
10727 } else if (!b.intent.requested) {
10728 requestServiceBindingLocked(s, b.intent, false);
10729 }
10730
10731 Binder.restoreCallingIdentity(origId);
10732 }
10733
10734 return 1;
10735 }
10736
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070010737 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010738 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010739 IBinder binder = c.conn.asBinder();
10740 AppBindRecord b = c.binding;
10741 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010742 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
10743 if (clist != null) {
10744 clist.remove(c);
10745 if (clist.size() == 0) {
10746 s.connections.remove(binder);
10747 }
10748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010749 b.connections.remove(c);
10750 if (c.activity != null && c.activity != skipAct) {
10751 if (c.activity.connections != null) {
10752 c.activity.connections.remove(c);
10753 }
10754 }
10755 if (b.client != skipApp) {
10756 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010757 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
10758 b.client.updateHasAboveClientLocked();
10759 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010760 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010761 clist = mServiceConnections.get(binder);
10762 if (clist != null) {
10763 clist.remove(c);
10764 if (clist.size() == 0) {
10765 mServiceConnections.remove(binder);
10766 }
10767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010768
10769 if (b.connections.size() == 0) {
10770 b.intent.apps.remove(b.client);
10771 }
10772
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010773 if (!c.serviceDead) {
10774 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
10775 + ": shouldUnbind=" + b.intent.hasBound);
10776 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
10777 && b.intent.hasBound) {
10778 try {
10779 bumpServiceExecutingLocked(s, "unbind");
10780 updateOomAdjLocked(s.app);
10781 b.intent.hasBound = false;
10782 // Assume the client doesn't want to know about a rebind;
10783 // we will deal with that later if it asks for one.
10784 b.intent.doRebind = false;
10785 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
10786 } catch (Exception e) {
10787 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
10788 serviceDoneExecutingLocked(s, true);
10789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010790 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010791
10792 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
10793 bringDownServiceLocked(s, false);
10794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010795 }
10796 }
10797
10798 public boolean unbindService(IServiceConnection connection) {
10799 synchronized (this) {
10800 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010801 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010802 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
10803 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010804 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010805 + connection.asBinder());
10806 return false;
10807 }
10808
10809 final long origId = Binder.clearCallingIdentity();
10810
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010811 while (clist.size() > 0) {
10812 ConnectionRecord r = clist.get(0);
10813 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010814
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010815 if (r.binding.service.app != null) {
10816 // This could have made the service less important.
10817 updateOomAdjLocked(r.binding.service.app);
10818 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010819 }
10820
10821 Binder.restoreCallingIdentity(origId);
10822 }
10823
10824 return true;
10825 }
10826
10827 public void publishService(IBinder token, Intent intent, IBinder service) {
10828 // Refuse possible leaked file descriptors
10829 if (intent != null && intent.hasFileDescriptors() == true) {
10830 throw new IllegalArgumentException("File descriptors passed in Intent");
10831 }
10832
10833 synchronized(this) {
10834 if (!(token instanceof ServiceRecord)) {
10835 throw new IllegalArgumentException("Invalid service token");
10836 }
10837 ServiceRecord r = (ServiceRecord)token;
10838
10839 final long origId = Binder.clearCallingIdentity();
10840
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010841 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010842 + " " + intent + ": " + service);
10843 if (r != null) {
10844 Intent.FilterComparison filter
10845 = new Intent.FilterComparison(intent);
10846 IntentBindRecord b = r.bindings.get(filter);
10847 if (b != null && !b.received) {
10848 b.binder = service;
10849 b.requested = true;
10850 b.received = true;
10851 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010852 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010853 = r.connections.values().iterator();
10854 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010855 ArrayList<ConnectionRecord> clist = it.next();
10856 for (int i=0; i<clist.size(); i++) {
10857 ConnectionRecord c = clist.get(i);
10858 if (!filter.equals(c.binding.intent.intent)) {
10859 if (DEBUG_SERVICE) Slog.v(
10860 TAG, "Not publishing to: " + c);
10861 if (DEBUG_SERVICE) Slog.v(
10862 TAG, "Bound intent: " + c.binding.intent.intent);
10863 if (DEBUG_SERVICE) Slog.v(
10864 TAG, "Published intent: " + intent);
10865 continue;
10866 }
10867 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
10868 try {
10869 c.conn.connected(r.name, service);
10870 } catch (Exception e) {
10871 Slog.w(TAG, "Failure sending service " + r.name +
10872 " to connection " + c.conn.asBinder() +
10873 " (in " + c.binding.client.processName + ")", e);
10874 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010875 }
10876 }
10877 }
10878 }
10879
10880 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
10881
10882 Binder.restoreCallingIdentity(origId);
10883 }
10884 }
10885 }
10886
10887 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10888 // Refuse possible leaked file descriptors
10889 if (intent != null && intent.hasFileDescriptors() == true) {
10890 throw new IllegalArgumentException("File descriptors passed in Intent");
10891 }
10892
10893 synchronized(this) {
10894 if (!(token instanceof ServiceRecord)) {
10895 throw new IllegalArgumentException("Invalid service token");
10896 }
10897 ServiceRecord r = (ServiceRecord)token;
10898
10899 final long origId = Binder.clearCallingIdentity();
10900
10901 if (r != null) {
10902 Intent.FilterComparison filter
10903 = new Intent.FilterComparison(intent);
10904 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080010905 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010906 + " at " + b + ": apps="
10907 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020010908
10909 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010910 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020010911 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 // Applications have already bound since the last
10913 // unbind, so just rebind right here.
10914 requestServiceBindingLocked(r, b, true);
10915 } else {
10916 // Note to tell the service the next time there is
10917 // a new client.
10918 b.doRebind = true;
10919 }
10920 }
10921
Per Edelberg78f9fff2010-08-30 20:01:35 +020010922 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010923
10924 Binder.restoreCallingIdentity(origId);
10925 }
10926 }
10927 }
10928
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010929 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010930 synchronized(this) {
10931 if (!(token instanceof ServiceRecord)) {
10932 throw new IllegalArgumentException("Invalid service token");
10933 }
10934 ServiceRecord r = (ServiceRecord)token;
10935 boolean inStopping = mStoppingServices.contains(token);
10936 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010937 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010938 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010939 + " with incorrect token: given " + token
10940 + ", expected " + r);
10941 return;
10942 }
10943
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010944 if (type == 1) {
10945 // This is a call from a service start... take care of
10946 // book-keeping.
10947 r.callStart = true;
10948 switch (res) {
10949 case Service.START_STICKY_COMPATIBILITY:
10950 case Service.START_STICKY: {
10951 // We are done with the associated start arguments.
10952 r.findDeliveredStart(startId, true);
10953 // Don't stop if killed.
10954 r.stopIfKilled = false;
10955 break;
10956 }
10957 case Service.START_NOT_STICKY: {
10958 // We are done with the associated start arguments.
10959 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010960 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010961 // There is no more work, and this service
10962 // doesn't want to hang around if killed.
10963 r.stopIfKilled = true;
10964 }
10965 break;
10966 }
10967 case Service.START_REDELIVER_INTENT: {
10968 // We'll keep this item until they explicitly
10969 // call stop for it, but keep track of the fact
10970 // that it was delivered.
10971 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
10972 if (si != null) {
10973 si.deliveryCount = 0;
10974 si.doneExecutingCount++;
10975 // Don't stop if killed.
10976 r.stopIfKilled = true;
10977 }
10978 break;
10979 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010980 case Service.START_TASK_REMOVED_COMPLETE: {
10981 // Special processing for onTaskRemoved(). Don't
10982 // impact normal onStartCommand() processing.
10983 r.findDeliveredStart(startId, true);
10984 break;
10985 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010986 default:
10987 throw new IllegalArgumentException(
10988 "Unknown service start result: " + res);
10989 }
10990 if (res == Service.START_STICKY_COMPATIBILITY) {
10991 r.callStart = false;
10992 }
10993 }
10994
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010995 final long origId = Binder.clearCallingIdentity();
10996 serviceDoneExecutingLocked(r, inStopping);
10997 Binder.restoreCallingIdentity(origId);
10998 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010999 Slog.w(TAG, "Done executing unknown service from pid "
11000 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011001 }
11002 }
11003 }
11004
11005 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011006 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11007 + ": nesting=" + r.executeNesting
11008 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011009 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011010 r.executeNesting--;
11011 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011012 if (DEBUG_SERVICE) Slog.v(TAG,
11013 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011014 r.app.executingServices.remove(r);
11015 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011016 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11017 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011018 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11019 }
11020 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011021 if (DEBUG_SERVICE) Slog.v(TAG,
11022 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011023 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011024 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011025 }
11026 updateOomAdjLocked(r.app);
11027 }
11028 }
11029
11030 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011031 String anrMessage = null;
11032
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011033 synchronized(this) {
11034 if (proc.executingServices.size() == 0 || proc.thread == null) {
11035 return;
11036 }
11037 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11038 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11039 ServiceRecord timeout = null;
11040 long nextTime = 0;
11041 while (it.hasNext()) {
11042 ServiceRecord sr = it.next();
11043 if (sr.executingStart < maxTime) {
11044 timeout = sr;
11045 break;
11046 }
11047 if (sr.executingStart > nextTime) {
11048 nextTime = sr.executingStart;
11049 }
11050 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011051 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011052 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011053 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011054 } else {
11055 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11056 msg.obj = proc;
11057 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11058 }
11059 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011060
11061 if (anrMessage != null) {
11062 appNotResponding(proc, null, null, anrMessage);
11063 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011064 }
11065
11066 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011067 // BACKUP AND RESTORE
11068 // =========================================================
11069
11070 // Cause the target app to be launched if necessary and its backup agent
11071 // instantiated. The backup agent will invoke backupAgentCreated() on the
11072 // activity manager to announce its creation.
11073 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011074 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011075 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11076
11077 synchronized(this) {
11078 // !!! TODO: currently no check here that we're already bound
11079 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11080 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11081 synchronized (stats) {
11082 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11083 }
11084
Dianne Hackborne7f97212011-02-24 14:40:20 -080011085 // Backup agent is now in use, its package can't be stopped.
11086 try {
11087 AppGlobals.getPackageManager().setPackageStoppedState(
11088 app.packageName, false);
11089 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011090 } catch (IllegalArgumentException e) {
11091 Slog.w(TAG, "Failed trying to unstop package "
11092 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011093 }
11094
Christopher Tate181fafa2009-05-14 11:12:14 -070011095 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011096 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11097 ? new ComponentName(app.packageName, app.backupAgentName)
11098 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011099 // startProcessLocked() returns existing proc's record if it's already running
11100 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011101 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011102 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011103 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011104 return false;
11105 }
11106
11107 r.app = proc;
11108 mBackupTarget = r;
11109 mBackupAppName = app.packageName;
11110
Christopher Tate6fa95972009-06-05 18:43:55 -070011111 // Try not to kill the process during backup
11112 updateOomAdjLocked(proc);
11113
Christopher Tate181fafa2009-05-14 11:12:14 -070011114 // If the process is already attached, schedule the creation of the backup agent now.
11115 // If it is not yet live, this will be done when it attaches to the framework.
11116 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011117 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011118 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011119 proc.thread.scheduleCreateBackupAgent(app,
11120 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011121 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011122 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011123 }
11124 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011125 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011126 }
11127 // Invariants: at this point, the target app process exists and the application
11128 // is either already running or in the process of coming up. mBackupTarget and
11129 // mBackupAppName describe the app, so that when it binds back to the AM we
11130 // know that it's scheduled for a backup-agent operation.
11131 }
11132
11133 return true;
11134 }
11135
11136 // A backup agent has just come up
11137 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011138 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011139 + " = " + agent);
11140
11141 synchronized(this) {
11142 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011143 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011144 return;
11145 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011146 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011147
Dianne Hackborn06740692010-09-22 22:46:21 -070011148 long oldIdent = Binder.clearCallingIdentity();
11149 try {
11150 IBackupManager bm = IBackupManager.Stub.asInterface(
11151 ServiceManager.getService(Context.BACKUP_SERVICE));
11152 bm.agentConnected(agentPackageName, agent);
11153 } catch (RemoteException e) {
11154 // can't happen; the backup manager service is local
11155 } catch (Exception e) {
11156 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11157 e.printStackTrace();
11158 } finally {
11159 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011160 }
11161 }
11162
11163 // done with this agent
11164 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011165 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011166 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011167 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011168 return;
11169 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011170
11171 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011172 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011173 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011174 return;
11175 }
11176
Christopher Tate181fafa2009-05-14 11:12:14 -070011177 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011178 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011179 return;
11180 }
11181
Christopher Tate6fa95972009-06-05 18:43:55 -070011182 ProcessRecord proc = mBackupTarget.app;
11183 mBackupTarget = null;
11184 mBackupAppName = null;
11185
11186 // Not backing this app up any more; reset its OOM adjustment
11187 updateOomAdjLocked(proc);
11188
Christopher Tatec7b31e32009-06-10 15:49:30 -070011189 // If the app crashed during backup, 'thread' will be null here
11190 if (proc.thread != null) {
11191 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011192 proc.thread.scheduleDestroyBackupAgent(appInfo,
11193 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011194 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011195 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011196 e.printStackTrace();
11197 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011198 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011199 }
11200 }
11201 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011202 // BROADCASTS
11203 // =========================================================
11204
Josh Bartel7f208742010-02-25 11:01:44 -060011205 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011206 List cur) {
11207 final ContentResolver resolver = mContext.getContentResolver();
11208 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11209 if (list == null) {
11210 return cur;
11211 }
11212 int N = list.size();
11213 for (int i=0; i<N; i++) {
11214 Intent intent = list.get(i);
11215 if (filter.match(resolver, intent, true, TAG) >= 0) {
11216 if (cur == null) {
11217 cur = new ArrayList<Intent>();
11218 }
11219 cur.add(intent);
11220 }
11221 }
11222 return cur;
11223 }
11224
11225 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011226 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011227 + mBroadcastsScheduled);
11228
11229 if (mBroadcastsScheduled) {
11230 return;
11231 }
11232 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11233 mBroadcastsScheduled = true;
11234 }
11235
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011236 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011237 IIntentReceiver receiver, IntentFilter filter, String permission) {
11238 synchronized(this) {
11239 ProcessRecord callerApp = null;
11240 if (caller != null) {
11241 callerApp = getRecordForAppLocked(caller);
11242 if (callerApp == null) {
11243 throw new SecurityException(
11244 "Unable to find app for caller " + caller
11245 + " (pid=" + Binder.getCallingPid()
11246 + ") when registering receiver " + receiver);
11247 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011248 if (callerApp.info.uid != Process.SYSTEM_UID &&
11249 !callerApp.pkgList.contains(callerPackage)) {
11250 throw new SecurityException("Given caller package " + callerPackage
11251 + " is not running in process " + callerApp);
11252 }
11253 } else {
11254 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011255 }
11256
11257 List allSticky = null;
11258
11259 // Look for any matching sticky broadcasts...
11260 Iterator actions = filter.actionsIterator();
11261 if (actions != null) {
11262 while (actions.hasNext()) {
11263 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011264 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011265 }
11266 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011267 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011268 }
11269
11270 // The first sticky in the list is returned directly back to
11271 // the client.
11272 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11273
Joe Onorato8a9b2202010-02-26 18:56:32 -080011274 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011275 + ": " + sticky);
11276
11277 if (receiver == null) {
11278 return sticky;
11279 }
11280
11281 ReceiverList rl
11282 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11283 if (rl == null) {
11284 rl = new ReceiverList(this, callerApp,
11285 Binder.getCallingPid(),
11286 Binder.getCallingUid(), receiver);
11287 if (rl.app != null) {
11288 rl.app.receivers.add(rl);
11289 } else {
11290 try {
11291 receiver.asBinder().linkToDeath(rl, 0);
11292 } catch (RemoteException e) {
11293 return sticky;
11294 }
11295 rl.linkedToDeath = true;
11296 }
11297 mRegisteredReceivers.put(receiver.asBinder(), rl);
11298 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011299 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011300 rl.add(bf);
11301 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011302 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011303 }
11304 mReceiverResolver.addFilter(bf);
11305
11306 // Enqueue broadcasts for all existing stickies that match
11307 // this filter.
11308 if (allSticky != null) {
11309 ArrayList receivers = new ArrayList();
11310 receivers.add(bf);
11311
11312 int N = allSticky.size();
11313 for (int i=0; i<N; i++) {
11314 Intent intent = (Intent)allSticky.get(i);
11315 BroadcastRecord r = new BroadcastRecord(intent, null,
11316 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011317 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011318 if (mParallelBroadcasts.size() == 0) {
11319 scheduleBroadcastsLocked();
11320 }
11321 mParallelBroadcasts.add(r);
11322 }
11323 }
11324
11325 return sticky;
11326 }
11327 }
11328
11329 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011330 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011331
11332 boolean doNext = false;
11333
11334 synchronized(this) {
11335 ReceiverList rl
11336 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11337 if (rl != null) {
11338 if (rl.curBroadcast != null) {
11339 BroadcastRecord r = rl.curBroadcast;
11340 doNext = finishReceiverLocked(
11341 receiver.asBinder(), r.resultCode, r.resultData,
11342 r.resultExtras, r.resultAbort, true);
11343 }
11344
11345 if (rl.app != null) {
11346 rl.app.receivers.remove(rl);
11347 }
11348 removeReceiverLocked(rl);
11349 if (rl.linkedToDeath) {
11350 rl.linkedToDeath = false;
11351 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11352 }
11353 }
11354 }
11355
11356 if (!doNext) {
11357 return;
11358 }
11359
11360 final long origId = Binder.clearCallingIdentity();
11361 processNextBroadcast(false);
11362 trimApplications();
11363 Binder.restoreCallingIdentity(origId);
11364 }
11365
11366 void removeReceiverLocked(ReceiverList rl) {
11367 mRegisteredReceivers.remove(rl.receiver.asBinder());
11368 int N = rl.size();
11369 for (int i=0; i<N; i++) {
11370 mReceiverResolver.removeFilter(rl.get(i));
11371 }
11372 }
11373
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011374 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
11375 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11376 ProcessRecord r = mLruProcesses.get(i);
11377 if (r.thread != null) {
11378 try {
11379 r.thread.dispatchPackageBroadcast(cmd, packages);
11380 } catch (RemoteException ex) {
11381 }
11382 }
11383 }
11384 }
11385
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011386 private final int broadcastIntentLocked(ProcessRecord callerApp,
11387 String callerPackage, Intent intent, String resolvedType,
11388 IIntentReceiver resultTo, int resultCode, String resultData,
11389 Bundle map, String requiredPermission,
11390 boolean ordered, boolean sticky, int callingPid, int callingUid) {
11391 intent = new Intent(intent);
11392
Dianne Hackborne7f97212011-02-24 14:40:20 -080011393 // By default broadcasts do not go to stopped apps.
11394 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11395
Joe Onorato8a9b2202010-02-26 18:56:32 -080011396 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011397 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
11398 + " ordered=" + ordered);
11399 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011400 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011401 }
11402
11403 // Handle special intents: if this broadcast is from the package
11404 // manager about a package being removed, we need to remove all of
11405 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011406 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011407 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011408 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11409 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011410 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011411 || uidRemoved) {
11412 if (checkComponentPermission(
11413 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011414 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011415 == PackageManager.PERMISSION_GRANTED) {
11416 if (uidRemoved) {
11417 final Bundle intentExtras = intent.getExtras();
11418 final int uid = intentExtras != null
11419 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11420 if (uid >= 0) {
11421 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11422 synchronized (bs) {
11423 bs.removeUidStatsLocked(uid);
11424 }
11425 }
11426 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011427 // If resources are unvailble just force stop all
11428 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011429 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011430 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11431 if (list != null && (list.length > 0)) {
11432 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070011433 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011434 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011435 sendPackageBroadcastLocked(
11436 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011437 }
11438 } else {
11439 Uri data = intent.getData();
11440 String ssp;
11441 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11442 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11443 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070011444 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011445 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011446 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011447 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
11448 new String[] {ssp});
11449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011450 }
11451 }
11452 }
11453 } else {
11454 String msg = "Permission Denial: " + intent.getAction()
11455 + " broadcast from " + callerPackage + " (pid=" + callingPid
11456 + ", uid=" + callingUid + ")"
11457 + " requires "
11458 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011459 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011460 throw new SecurityException(msg);
11461 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011462
11463 // Special case for adding a package: by default turn on compatibility
11464 // mode.
11465 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011466 Uri data = intent.getData();
11467 String ssp;
11468 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11469 mCompatModePackages.handlePackageAddedLocked(ssp,
11470 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011472 }
11473
11474 /*
11475 * If this is the time zone changed action, queue up a message that will reset the timezone
11476 * of all currently running processes. This message will get queued up before the broadcast
11477 * happens.
11478 */
11479 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11480 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11481 }
11482
Robert Greenwalt03595d02010-11-02 14:08:23 -070011483 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11484 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11485 }
11486
Robert Greenwalt434203a2010-10-11 16:00:27 -070011487 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11488 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11489 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11490 }
11491
Dianne Hackborn854060af2009-07-09 18:14:31 -070011492 /*
11493 * Prevent non-system code (defined here to be non-persistent
11494 * processes) from sending protected broadcasts.
11495 */
11496 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11497 || callingUid == Process.SHELL_UID || callingUid == 0) {
11498 // Always okay.
11499 } else if (callerApp == null || !callerApp.persistent) {
11500 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011501 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070011502 intent.getAction())) {
11503 String msg = "Permission Denial: not allowed to send broadcast "
11504 + intent.getAction() + " from pid="
11505 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011506 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011507 throw new SecurityException(msg);
11508 }
11509 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011510 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070011511 return BROADCAST_SUCCESS;
11512 }
11513 }
11514
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011515 // Add to the sticky list if requested.
11516 if (sticky) {
11517 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11518 callingPid, callingUid)
11519 != PackageManager.PERMISSION_GRANTED) {
11520 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11521 + callingPid + ", uid=" + callingUid
11522 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011523 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011524 throw new SecurityException(msg);
11525 }
11526 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011527 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011528 + " and enforce permission " + requiredPermission);
11529 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
11530 }
11531 if (intent.getComponent() != null) {
11532 throw new SecurityException(
11533 "Sticky broadcasts can't target a specific component");
11534 }
11535 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11536 if (list == null) {
11537 list = new ArrayList<Intent>();
11538 mStickyBroadcasts.put(intent.getAction(), list);
11539 }
11540 int N = list.size();
11541 int i;
11542 for (i=0; i<N; i++) {
11543 if (intent.filterEquals(list.get(i))) {
11544 // This sticky already exists, replace it.
11545 list.set(i, new Intent(intent));
11546 break;
11547 }
11548 }
11549 if (i >= N) {
11550 list.add(new Intent(intent));
11551 }
11552 }
11553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011554 // Figure out who all will receive this broadcast.
11555 List receivers = null;
11556 List<BroadcastFilter> registeredReceivers = null;
11557 try {
11558 if (intent.getComponent() != null) {
11559 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011560 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070011561 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011562 if (ai != null) {
11563 receivers = new ArrayList();
11564 ResolveInfo ri = new ResolveInfo();
11565 ri.activityInfo = ai;
11566 receivers.add(ri);
11567 }
11568 } else {
11569 // Need to resolve the intent to interested receivers...
11570 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11571 == 0) {
11572 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011573 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011574 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011575 }
Mihai Preda074edef2009-05-18 17:13:31 +020011576 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011577 }
11578 } catch (RemoteException ex) {
11579 // pm is in same process, this will never happen.
11580 }
11581
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011582 final boolean replacePending =
11583 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11584
Joe Onorato8a9b2202010-02-26 18:56:32 -080011585 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011586 + " replacePending=" + replacePending);
11587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011588 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11589 if (!ordered && NR > 0) {
11590 // If we are not serializing this broadcast, then send the
11591 // registered receivers separately so they don't wait for the
11592 // components to be launched.
11593 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11594 callerPackage, callingPid, callingUid, requiredPermission,
11595 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011596 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011597 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011598 TAG, "Enqueueing parallel broadcast " + r
11599 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011600 boolean replaced = false;
11601 if (replacePending) {
11602 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
11603 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011604 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011605 "***** DROPPING PARALLEL: " + intent);
11606 mParallelBroadcasts.set(i, r);
11607 replaced = true;
11608 break;
11609 }
11610 }
11611 }
11612 if (!replaced) {
11613 mParallelBroadcasts.add(r);
11614 scheduleBroadcastsLocked();
11615 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011616 registeredReceivers = null;
11617 NR = 0;
11618 }
11619
11620 // Merge into one list.
11621 int ir = 0;
11622 if (receivers != null) {
11623 // A special case for PACKAGE_ADDED: do not allow the package
11624 // being added to see this broadcast. This prevents them from
11625 // using this as a back door to get run as soon as they are
11626 // installed. Maybe in the future we want to have a special install
11627 // broadcast or such for apps, but we'd like to deliberately make
11628 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011629 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011630 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11631 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11632 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011633 Uri data = intent.getData();
11634 if (data != null) {
11635 String pkgName = data.getSchemeSpecificPart();
11636 if (pkgName != null) {
11637 skipPackages = new String[] { pkgName };
11638 }
11639 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011640 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011641 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011642 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011643 if (skipPackages != null && (skipPackages.length > 0)) {
11644 for (String skipPackage : skipPackages) {
11645 if (skipPackage != null) {
11646 int NT = receivers.size();
11647 for (int it=0; it<NT; it++) {
11648 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11649 if (curt.activityInfo.packageName.equals(skipPackage)) {
11650 receivers.remove(it);
11651 it--;
11652 NT--;
11653 }
11654 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011655 }
11656 }
11657 }
11658
11659 int NT = receivers != null ? receivers.size() : 0;
11660 int it = 0;
11661 ResolveInfo curt = null;
11662 BroadcastFilter curr = null;
11663 while (it < NT && ir < NR) {
11664 if (curt == null) {
11665 curt = (ResolveInfo)receivers.get(it);
11666 }
11667 if (curr == null) {
11668 curr = registeredReceivers.get(ir);
11669 }
11670 if (curr.getPriority() >= curt.priority) {
11671 // Insert this broadcast record into the final list.
11672 receivers.add(it, curr);
11673 ir++;
11674 curr = null;
11675 it++;
11676 NT++;
11677 } else {
11678 // Skip to the next ResolveInfo in the final list.
11679 it++;
11680 curt = null;
11681 }
11682 }
11683 }
11684 while (ir < NR) {
11685 if (receivers == null) {
11686 receivers = new ArrayList();
11687 }
11688 receivers.add(registeredReceivers.get(ir));
11689 ir++;
11690 }
11691
11692 if ((receivers != null && receivers.size() > 0)
11693 || resultTo != null) {
11694 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
11695 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011696 receivers, resultTo, resultCode, resultData, map, ordered,
11697 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011698 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011699 TAG, "Enqueueing ordered broadcast " + r
11700 + ": prev had " + mOrderedBroadcasts.size());
11701 if (DEBUG_BROADCAST) {
11702 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011703 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011704 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011705 boolean replaced = false;
11706 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011707 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011708 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011709 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011710 "***** DROPPING ORDERED: " + intent);
11711 mOrderedBroadcasts.set(i, r);
11712 replaced = true;
11713 break;
11714 }
11715 }
11716 }
11717 if (!replaced) {
11718 mOrderedBroadcasts.add(r);
11719 scheduleBroadcastsLocked();
11720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011721 }
11722
11723 return BROADCAST_SUCCESS;
11724 }
11725
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011726 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011727 // Refuse possible leaked file descriptors
11728 if (intent != null && intent.hasFileDescriptors() == true) {
11729 throw new IllegalArgumentException("File descriptors passed in Intent");
11730 }
11731
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011732 int flags = intent.getFlags();
11733
11734 if (!mProcessesReady) {
11735 // if the caller really truly claims to know what they're doing, go
11736 // ahead and allow the broadcast without launching any receivers
11737 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11738 intent = new Intent(intent);
11739 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11740 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11741 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11742 + " before boot completion");
11743 throw new IllegalStateException("Cannot broadcast before boot completed");
11744 }
11745 }
11746
11747 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11748 throw new IllegalArgumentException(
11749 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11750 }
11751
11752 return intent;
11753 }
11754
11755 public final int broadcastIntent(IApplicationThread caller,
11756 Intent intent, String resolvedType, IIntentReceiver resultTo,
11757 int resultCode, String resultData, Bundle map,
11758 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011759 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011760 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011762 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11763 final int callingPid = Binder.getCallingPid();
11764 final int callingUid = Binder.getCallingUid();
11765 final long origId = Binder.clearCallingIdentity();
11766 int res = broadcastIntentLocked(callerApp,
11767 callerApp != null ? callerApp.info.packageName : null,
11768 intent, resolvedType, resultTo,
11769 resultCode, resultData, map, requiredPermission, serialized,
11770 sticky, callingPid, callingUid);
11771 Binder.restoreCallingIdentity(origId);
11772 return res;
11773 }
11774 }
11775
11776 int broadcastIntentInPackage(String packageName, int uid,
11777 Intent intent, String resolvedType, IIntentReceiver resultTo,
11778 int resultCode, String resultData, Bundle map,
11779 String requiredPermission, boolean serialized, boolean sticky) {
11780 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011781 intent = verifyBroadcastLocked(intent);
11782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011783 final long origId = Binder.clearCallingIdentity();
11784 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11785 resultTo, resultCode, resultData, map, requiredPermission,
11786 serialized, sticky, -1, uid);
11787 Binder.restoreCallingIdentity(origId);
11788 return res;
11789 }
11790 }
11791
11792 public final void unbroadcastIntent(IApplicationThread caller,
11793 Intent intent) {
11794 // Refuse possible leaked file descriptors
11795 if (intent != null && intent.hasFileDescriptors() == true) {
11796 throw new IllegalArgumentException("File descriptors passed in Intent");
11797 }
11798
11799 synchronized(this) {
11800 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11801 != PackageManager.PERMISSION_GRANTED) {
11802 String msg = "Permission Denial: unbroadcastIntent() from pid="
11803 + Binder.getCallingPid()
11804 + ", uid=" + Binder.getCallingUid()
11805 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011806 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011807 throw new SecurityException(msg);
11808 }
11809 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
11810 if (list != null) {
11811 int N = list.size();
11812 int i;
11813 for (i=0; i<N; i++) {
11814 if (intent.filterEquals(list.get(i))) {
11815 list.remove(i);
11816 break;
11817 }
11818 }
11819 }
11820 }
11821 }
11822
11823 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11824 String resultData, Bundle resultExtras, boolean resultAbort,
11825 boolean explicit) {
11826 if (mOrderedBroadcasts.size() == 0) {
11827 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011828 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011829 }
11830 return false;
11831 }
11832 BroadcastRecord r = mOrderedBroadcasts.get(0);
11833 if (r.receiver == null) {
11834 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011835 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011836 }
11837 return false;
11838 }
11839 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011840 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841 return false;
11842 }
11843 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011844 r.state = BroadcastRecord.IDLE;
11845 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011846 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011847 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011848 }
11849 }
11850 r.receiver = null;
11851 r.intent.setComponent(null);
11852 if (r.curApp != null) {
11853 r.curApp.curReceiver = null;
11854 }
11855 if (r.curFilter != null) {
11856 r.curFilter.receiverList.curBroadcast = null;
11857 }
11858 r.curFilter = null;
11859 r.curApp = null;
11860 r.curComponent = null;
11861 r.curReceiver = null;
11862 mPendingBroadcast = null;
11863
11864 r.resultCode = resultCode;
11865 r.resultData = resultData;
11866 r.resultExtras = resultExtras;
11867 r.resultAbort = resultAbort;
11868
11869 // We will process the next receiver right now if this is finishing
11870 // an app receiver (which is always asynchronous) or after we have
11871 // come back from calling a receiver.
11872 return state == BroadcastRecord.APP_RECEIVE
11873 || state == BroadcastRecord.CALL_DONE_RECEIVE;
11874 }
11875
11876 public void finishReceiver(IBinder who, int resultCode, String resultData,
11877 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011878 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011879
11880 // Refuse possible leaked file descriptors
11881 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11882 throw new IllegalArgumentException("File descriptors passed in Bundle");
11883 }
11884
11885 boolean doNext;
11886
11887 final long origId = Binder.clearCallingIdentity();
11888
11889 synchronized(this) {
11890 doNext = finishReceiverLocked(
11891 who, resultCode, resultData, resultExtras, resultAbort, true);
11892 }
11893
11894 if (doNext) {
11895 processNextBroadcast(false);
11896 }
11897 trimApplications();
11898
11899 Binder.restoreCallingIdentity(origId);
11900 }
11901
Jeff Brown4d94a762010-09-23 11:33:28 -070011902 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011903 if (r.nextReceiver > 0) {
11904 Object curReceiver = r.receivers.get(r.nextReceiver-1);
11905 if (curReceiver instanceof BroadcastFilter) {
11906 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080011907 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011908 System.identityHashCode(r),
11909 r.intent.getAction(),
11910 r.nextReceiver - 1,
11911 System.identityHashCode(bf));
11912 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080011913 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011914 System.identityHashCode(r),
11915 r.intent.getAction(),
11916 r.nextReceiver - 1,
11917 ((ResolveInfo)curReceiver).toString());
11918 }
11919 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011920 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011922 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011923 System.identityHashCode(r),
11924 r.intent.getAction(),
11925 r.nextReceiver,
11926 "NONE");
11927 }
11928 }
11929
Jeff Brown4d94a762010-09-23 11:33:28 -070011930 private final void setBroadcastTimeoutLocked(long timeoutTime) {
11931 if (! mPendingBroadcastTimeoutMessage) {
11932 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
11933 mHandler.sendMessageAtTime(msg, timeoutTime);
11934 mPendingBroadcastTimeoutMessage = true;
11935 }
11936 }
11937
11938 private final void cancelBroadcastTimeoutLocked() {
11939 if (mPendingBroadcastTimeoutMessage) {
11940 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
11941 mPendingBroadcastTimeoutMessage = false;
11942 }
11943 }
11944
11945 private final void broadcastTimeoutLocked(boolean fromMsg) {
11946 if (fromMsg) {
11947 mPendingBroadcastTimeoutMessage = false;
11948 }
11949
11950 if (mOrderedBroadcasts.size() == 0) {
11951 return;
11952 }
11953
11954 long now = SystemClock.uptimeMillis();
11955 BroadcastRecord r = mOrderedBroadcasts.get(0);
11956 if (fromMsg) {
11957 if (mDidDexOpt) {
11958 // Delay timeouts until dexopt finishes.
11959 mDidDexOpt = false;
11960 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
11961 setBroadcastTimeoutLocked(timeoutTime);
11962 return;
11963 }
11964 if (! mProcessesReady) {
11965 // Only process broadcast timeouts if the system is ready. That way
11966 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
11967 // to do heavy lifting for system up.
11968 return;
11969 }
11970
11971 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
11972 if (timeoutTime > now) {
11973 // We can observe premature timeouts because we do not cancel and reset the
11974 // broadcast timeout message after each receiver finishes. Instead, we set up
11975 // an initial timeout then kick it down the road a little further as needed
11976 // when it expires.
11977 if (DEBUG_BROADCAST) Slog.v(TAG,
11978 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
11979 + timeoutTime);
11980 setBroadcastTimeoutLocked(timeoutTime);
11981 return;
11982 }
11983 }
11984
11985 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
11986 + ", started " + (now - r.receiverTime) + "ms ago");
11987 r.receiverTime = now;
11988 r.anrCount++;
11989
11990 // Current receiver has passed its expiration date.
11991 if (r.nextReceiver <= 0) {
11992 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
11993 return;
11994 }
11995
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011996 ProcessRecord app = null;
11997 String anrMessage = null;
11998
Jeff Brown4d94a762010-09-23 11:33:28 -070011999 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12000 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12001 logBroadcastReceiverDiscardLocked(r);
12002 if (curReceiver instanceof BroadcastFilter) {
12003 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12004 if (bf.receiverList.pid != 0
12005 && bf.receiverList.pid != MY_PID) {
12006 synchronized (this.mPidsSelfLocked) {
12007 app = this.mPidsSelfLocked.get(
12008 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012010 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012011 } else {
12012 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012014
Jeff Brown4d94a762010-09-23 11:33:28 -070012015 if (app != null) {
12016 anrMessage = "Broadcast of " + r.intent.toString();
12017 }
12018
12019 if (mPendingBroadcast == r) {
12020 mPendingBroadcast = null;
12021 }
12022
12023 // Move on to the next receiver.
12024 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12025 r.resultExtras, r.resultAbort, true);
12026 scheduleBroadcastsLocked();
12027
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012028 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012029 // Post the ANR to the handler since we do not want to process ANRs while
12030 // potentially holding our lock.
12031 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012033 }
12034
12035 private final void processCurBroadcastLocked(BroadcastRecord r,
12036 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012037 if (DEBUG_BROADCAST) Slog.v(TAG,
12038 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012039 if (app.thread == null) {
12040 throw new RemoteException();
12041 }
12042 r.receiver = app.thread.asBinder();
12043 r.curApp = app;
12044 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012045 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012046
12047 // Tell the application to launch this receiver.
12048 r.intent.setComponent(r.curComponent);
12049
12050 boolean started = false;
12051 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012052 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012053 "Delivering to component " + r.curComponent
12054 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012055 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012056 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012057 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012059 if (DEBUG_BROADCAST) Slog.v(TAG,
12060 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012061 started = true;
12062 } finally {
12063 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012064 if (DEBUG_BROADCAST) Slog.v(TAG,
12065 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012066 r.receiver = null;
12067 r.curApp = null;
12068 app.curReceiver = null;
12069 }
12070 }
12071
12072 }
12073
Jeff Brown4d94a762010-09-23 11:33:28 -070012074 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012075 Intent intent, int resultCode, String data, Bundle extras,
12076 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012077 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012078 if (app != null && app.thread != null) {
12079 // If we have an app thread, do the call through that so it is
12080 // correctly ordered with other one-way calls.
12081 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012082 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012083 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012084 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012085 }
12086 }
12087
Jeff Brown4d94a762010-09-23 11:33:28 -070012088 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012089 BroadcastFilter filter, boolean ordered) {
12090 boolean skip = false;
12091 if (filter.requiredPermission != null) {
12092 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012093 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012094 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012095 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012096 + r.intent.toString()
12097 + " from " + r.callerPackage + " (pid="
12098 + r.callingPid + ", uid=" + r.callingUid + ")"
12099 + " requires " + filter.requiredPermission
12100 + " due to registered receiver " + filter);
12101 skip = true;
12102 }
12103 }
12104 if (r.requiredPermission != null) {
12105 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012106 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012107 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012108 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012109 + r.intent.toString()
12110 + " to " + filter.receiverList.app
12111 + " (pid=" + filter.receiverList.pid
12112 + ", uid=" + filter.receiverList.uid + ")"
12113 + " requires " + r.requiredPermission
12114 + " due to sender " + r.callerPackage
12115 + " (uid " + r.callingUid + ")");
12116 skip = true;
12117 }
12118 }
12119
12120 if (!skip) {
12121 // If this is not being sent as an ordered broadcast, then we
12122 // don't want to touch the fields that keep track of the current
12123 // state of ordered broadcasts.
12124 if (ordered) {
12125 r.receiver = filter.receiverList.receiver.asBinder();
12126 r.curFilter = filter;
12127 filter.receiverList.curBroadcast = r;
12128 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012129 if (filter.receiverList.app != null) {
12130 // Bump hosting application to no longer be in background
12131 // scheduling class. Note that we can't do that if there
12132 // isn't an app... but we can only be in that case for
12133 // things that directly call the IActivityManager API, which
12134 // are already core system stuff so don't matter for this.
12135 r.curApp = filter.receiverList.app;
12136 filter.receiverList.app.curReceiver = r;
12137 updateOomAdjLocked();
12138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139 }
12140 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012141 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012142 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012143 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012144 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012145 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012146 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012147 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012148 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012149 if (ordered) {
12150 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12151 }
12152 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012153 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012154 if (ordered) {
12155 r.receiver = null;
12156 r.curFilter = null;
12157 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012158 if (filter.receiverList.app != null) {
12159 filter.receiverList.app.curReceiver = null;
12160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012161 }
12162 }
12163 }
12164 }
12165
Dianne Hackborn12527f92009-11-11 17:39:50 -080012166 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12167 if (r.callingUid < 0) {
12168 // This was from a registerReceiver() call; ignore it.
12169 return;
12170 }
12171 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12172 MAX_BROADCAST_HISTORY-1);
12173 r.finishTime = SystemClock.uptimeMillis();
12174 mBroadcastHistory[0] = r;
12175 }
12176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012177 private final void processNextBroadcast(boolean fromMsg) {
12178 synchronized(this) {
12179 BroadcastRecord r;
12180
Joe Onorato8a9b2202010-02-26 18:56:32 -080012181 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012182 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012183 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012184
12185 updateCpuStats();
12186
12187 if (fromMsg) {
12188 mBroadcastsScheduled = false;
12189 }
12190
12191 // First, deliver any non-serialized broadcasts right away.
12192 while (mParallelBroadcasts.size() > 0) {
12193 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012194 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012195 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012196 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012197 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012198 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012199 for (int i=0; i<N; i++) {
12200 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012201 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012202 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012203 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012204 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012205 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012206 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012207 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012208 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012209 }
12210
12211 // Now take care of the next serialized one...
12212
12213 // If we are waiting for a process to come up to handle the next
12214 // broadcast, then do nothing at this point. Just in case, we
12215 // check that the process we're waiting for still exists.
12216 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012217 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012218 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012219 + mPendingBroadcast.curApp);
12220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012221
12222 boolean isDead;
12223 synchronized (mPidsSelfLocked) {
12224 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12225 }
12226 if (!isDead) {
12227 // It's still alive, so keep waiting
12228 return;
12229 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012230 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012231 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012232 mPendingBroadcast.state = BroadcastRecord.IDLE;
12233 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012234 mPendingBroadcast = null;
12235 }
12236 }
12237
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012238 boolean looped = false;
12239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012240 do {
12241 if (mOrderedBroadcasts.size() == 0) {
12242 // No more broadcasts pending, so all done!
12243 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012244 if (looped) {
12245 // If we had finished the last ordered broadcast, then
12246 // make sure all processes have correct oom and sched
12247 // adjustments.
12248 updateOomAdjLocked();
12249 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012250 return;
12251 }
12252 r = mOrderedBroadcasts.get(0);
12253 boolean forceReceive = false;
12254
12255 // Ensure that even if something goes awry with the timeout
12256 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012257 // and continue to make progress.
12258 //
12259 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012260 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012261 // one time heavy lifting after system upgrades and can take
12262 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012263 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012264 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012265 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012266 if ((numReceivers > 0) &&
12267 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012268 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012269 + " now=" + now
12270 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012271 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012272 + " intent=" + r.intent
12273 + " numReceivers=" + numReceivers
12274 + " nextReceiver=" + r.nextReceiver
12275 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012276 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012277 forceReceive = true;
12278 r.state = BroadcastRecord.IDLE;
12279 }
12280 }
12281
12282 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012283 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 "processNextBroadcast() called when not idle (state="
12285 + r.state + ")");
12286 return;
12287 }
12288
12289 if (r.receivers == null || r.nextReceiver >= numReceivers
12290 || r.resultAbort || forceReceive) {
12291 // No more receivers for this broadcast! Send the final
12292 // result if requested...
12293 if (r.resultTo != null) {
12294 try {
12295 if (DEBUG_BROADCAST) {
12296 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012297 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012298 + " seq=" + seq + " app=" + r.callerApp);
12299 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012300 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012301 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012302 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012303 // Set this to null so that the reference
12304 // (local and remote) isnt kept in the mBroadcastHistory.
12305 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012306 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012307 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012308 }
12309 }
12310
Joe Onorato8a9b2202010-02-26 18:56:32 -080012311 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012312 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012313
Joe Onorato8a9b2202010-02-26 18:56:32 -080012314 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012315 + r);
12316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012317 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012318 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012319 mOrderedBroadcasts.remove(0);
12320 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012321 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012322 continue;
12323 }
12324 } while (r == null);
12325
12326 // Get the next receiver...
12327 int recIdx = r.nextReceiver++;
12328
12329 // Keep track of when this receiver started, and make sure there
12330 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012331 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012333 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012334 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012335 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012336 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012337 }
12338 if (! mPendingBroadcastTimeoutMessage) {
12339 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012340 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012341 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12342 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 }
12344
12345 Object nextReceiver = r.receivers.get(recIdx);
12346 if (nextReceiver instanceof BroadcastFilter) {
12347 // Simple case: this is a registered receiver who gets
12348 // a direct call.
12349 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012350 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012351 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012352 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012353 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012354 if (r.receiver == null || !r.ordered) {
12355 // The receiver has already finished, so schedule to
12356 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012357 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
12358 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 r.state = BroadcastRecord.IDLE;
12360 scheduleBroadcastsLocked();
12361 }
12362 return;
12363 }
12364
12365 // Hard case: need to instantiate the receiver, possibly
12366 // starting its application process to host it.
12367
12368 ResolveInfo info =
12369 (ResolveInfo)nextReceiver;
12370
12371 boolean skip = false;
12372 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012373 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
12374 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012375 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012376 if (!info.activityInfo.exported) {
12377 Slog.w(TAG, "Permission Denial: broadcasting "
12378 + r.intent.toString()
12379 + " from " + r.callerPackage + " (pid=" + r.callingPid
12380 + ", uid=" + r.callingUid + ")"
12381 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
12382 + " due to receiver " + info.activityInfo.packageName
12383 + "/" + info.activityInfo.name);
12384 } else {
12385 Slog.w(TAG, "Permission Denial: broadcasting "
12386 + r.intent.toString()
12387 + " from " + r.callerPackage + " (pid=" + r.callingPid
12388 + ", uid=" + r.callingUid + ")"
12389 + " requires " + info.activityInfo.permission
12390 + " due to receiver " + info.activityInfo.packageName
12391 + "/" + info.activityInfo.name);
12392 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012393 skip = true;
12394 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012395 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012396 r.requiredPermission != null) {
12397 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012398 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012399 checkPermission(r.requiredPermission,
12400 info.activityInfo.applicationInfo.packageName);
12401 } catch (RemoteException e) {
12402 perm = PackageManager.PERMISSION_DENIED;
12403 }
12404 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012405 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012406 + r.intent + " to "
12407 + info.activityInfo.applicationInfo.packageName
12408 + " requires " + r.requiredPermission
12409 + " due to sender " + r.callerPackage
12410 + " (uid " + r.callingUid + ")");
12411 skip = true;
12412 }
12413 }
12414 if (r.curApp != null && r.curApp.crashing) {
12415 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012416 if (DEBUG_BROADCAST) Slog.v(TAG,
12417 "Skipping deliver ordered " + r + " to " + r.curApp
12418 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012419 skip = true;
12420 }
12421
12422 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012423 if (DEBUG_BROADCAST) Slog.v(TAG,
12424 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012425 r.receiver = null;
12426 r.curFilter = null;
12427 r.state = BroadcastRecord.IDLE;
12428 scheduleBroadcastsLocked();
12429 return;
12430 }
12431
12432 r.state = BroadcastRecord.APP_RECEIVE;
12433 String targetProcess = info.activityInfo.processName;
12434 r.curComponent = new ComponentName(
12435 info.activityInfo.applicationInfo.packageName,
12436 info.activityInfo.name);
12437 r.curReceiver = info.activityInfo;
12438
Dianne Hackborne7f97212011-02-24 14:40:20 -080012439 // Broadcast is being executed, its package can't be stopped.
12440 try {
12441 AppGlobals.getPackageManager().setPackageStoppedState(
12442 r.curComponent.getPackageName(), false);
12443 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012444 } catch (IllegalArgumentException e) {
12445 Slog.w(TAG, "Failed trying to unstop package "
12446 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012447 }
12448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012449 // Is this receiver's application already running?
12450 ProcessRecord app = getProcessRecordLocked(targetProcess,
12451 info.activityInfo.applicationInfo.uid);
12452 if (app != null && app.thread != null) {
12453 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012454 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012455 processCurBroadcastLocked(r, app);
12456 return;
12457 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012458 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012459 + r.curComponent, e);
12460 }
12461
12462 // If a dead object exception was thrown -- fall through to
12463 // restart the application.
12464 }
12465
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012466 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012467 if (DEBUG_BROADCAST) Slog.v(TAG,
12468 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012469 if ((r.curApp=startProcessLocked(targetProcess,
12470 info.activityInfo.applicationInfo, true,
12471 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012472 "broadcast", r.curComponent,
12473 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
12474 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012475 // Ah, this recipient is unavailable. Finish it if necessary,
12476 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080012477 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012478 + info.activityInfo.applicationInfo.packageName + "/"
12479 + info.activityInfo.applicationInfo.uid + " for broadcast "
12480 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070012481 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012482 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12483 r.resultExtras, r.resultAbort, true);
12484 scheduleBroadcastsLocked();
12485 r.state = BroadcastRecord.IDLE;
12486 return;
12487 }
12488
12489 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012490 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012491 }
12492 }
12493
12494 // =========================================================
12495 // INSTRUMENTATION
12496 // =========================================================
12497
12498 public boolean startInstrumentation(ComponentName className,
12499 String profileFile, int flags, Bundle arguments,
12500 IInstrumentationWatcher watcher) {
12501 // Refuse possible leaked file descriptors
12502 if (arguments != null && arguments.hasFileDescriptors()) {
12503 throw new IllegalArgumentException("File descriptors passed in Bundle");
12504 }
12505
12506 synchronized(this) {
12507 InstrumentationInfo ii = null;
12508 ApplicationInfo ai = null;
12509 try {
12510 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012511 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012512 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012513 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012514 } catch (PackageManager.NameNotFoundException e) {
12515 }
12516 if (ii == null) {
12517 reportStartInstrumentationFailure(watcher, className,
12518 "Unable to find instrumentation info for: " + className);
12519 return false;
12520 }
12521 if (ai == null) {
12522 reportStartInstrumentationFailure(watcher, className,
12523 "Unable to find instrumentation target package: " + ii.targetPackage);
12524 return false;
12525 }
12526
12527 int match = mContext.getPackageManager().checkSignatures(
12528 ii.targetPackage, ii.packageName);
12529 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12530 String msg = "Permission Denial: starting instrumentation "
12531 + className + " from pid="
12532 + Binder.getCallingPid()
12533 + ", uid=" + Binder.getCallingPid()
12534 + " not allowed because package " + ii.packageName
12535 + " does not have a signature matching the target "
12536 + ii.targetPackage;
12537 reportStartInstrumentationFailure(watcher, className, msg);
12538 throw new SecurityException(msg);
12539 }
12540
12541 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012542 // Instrumentation can kill and relaunch even persistent processes
12543 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012544 ProcessRecord app = addAppLocked(ai);
12545 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012546 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012547 app.instrumentationProfileFile = profileFile;
12548 app.instrumentationArguments = arguments;
12549 app.instrumentationWatcher = watcher;
12550 app.instrumentationResultClass = className;
12551 Binder.restoreCallingIdentity(origId);
12552 }
12553
12554 return true;
12555 }
12556
12557 /**
12558 * Report errors that occur while attempting to start Instrumentation. Always writes the
12559 * error to the logs, but if somebody is watching, send the report there too. This enables
12560 * the "am" command to report errors with more information.
12561 *
12562 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12563 * @param cn The component name of the instrumentation.
12564 * @param report The error report.
12565 */
12566 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12567 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012568 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012569 try {
12570 if (watcher != null) {
12571 Bundle results = new Bundle();
12572 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12573 results.putString("Error", report);
12574 watcher.instrumentationStatus(cn, -1, results);
12575 }
12576 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012577 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012578 }
12579 }
12580
12581 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12582 if (app.instrumentationWatcher != null) {
12583 try {
12584 // NOTE: IInstrumentationWatcher *must* be oneway here
12585 app.instrumentationWatcher.instrumentationFinished(
12586 app.instrumentationClass,
12587 resultCode,
12588 results);
12589 } catch (RemoteException e) {
12590 }
12591 }
12592 app.instrumentationWatcher = null;
12593 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012594 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012595 app.instrumentationProfileFile = null;
12596 app.instrumentationArguments = null;
12597
Christopher Tate3dacd842011-08-19 14:56:15 -070012598 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012599 }
12600
12601 public void finishInstrumentation(IApplicationThread target,
12602 int resultCode, Bundle results) {
12603 // Refuse possible leaked file descriptors
12604 if (results != null && results.hasFileDescriptors()) {
12605 throw new IllegalArgumentException("File descriptors passed in Intent");
12606 }
12607
12608 synchronized(this) {
12609 ProcessRecord app = getRecordForAppLocked(target);
12610 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012611 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012612 return;
12613 }
12614 final long origId = Binder.clearCallingIdentity();
12615 finishInstrumentationLocked(app, resultCode, results);
12616 Binder.restoreCallingIdentity(origId);
12617 }
12618 }
12619
12620 // =========================================================
12621 // CONFIGURATION
12622 // =========================================================
12623
12624 public ConfigurationInfo getDeviceConfigurationInfo() {
12625 ConfigurationInfo config = new ConfigurationInfo();
12626 synchronized (this) {
12627 config.reqTouchScreen = mConfiguration.touchscreen;
12628 config.reqKeyboardType = mConfiguration.keyboard;
12629 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012630 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12631 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012632 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12633 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012634 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12635 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012636 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12637 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012638 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012639 }
12640 return config;
12641 }
12642
12643 public Configuration getConfiguration() {
12644 Configuration ci;
12645 synchronized(this) {
12646 ci = new Configuration(mConfiguration);
12647 }
12648 return ci;
12649 }
12650
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012651 public void updatePersistentConfiguration(Configuration values) {
12652 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12653 "updateConfiguration()");
12654 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12655 "updateConfiguration()");
12656 if (values == null) {
12657 throw new NullPointerException("Configuration must not be null");
12658 }
12659
12660 synchronized(this) {
12661 final long origId = Binder.clearCallingIdentity();
12662 updateConfigurationLocked(values, null, true);
12663 Binder.restoreCallingIdentity(origId);
12664 }
12665 }
12666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012667 public void updateConfiguration(Configuration values) {
12668 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12669 "updateConfiguration()");
12670
12671 synchronized(this) {
12672 if (values == null && mWindowManager != null) {
12673 // sentinel: fetch the current configuration from the window manager
12674 values = mWindowManager.computeNewConfiguration();
12675 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012676
12677 if (mWindowManager != null) {
12678 mProcessList.applyDisplaySize(mWindowManager);
12679 }
12680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012681 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012682 if (values != null) {
12683 Settings.System.clearConfiguration(values);
12684 }
12685 updateConfigurationLocked(values, null, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012686 Binder.restoreCallingIdentity(origId);
12687 }
12688 }
12689
12690 /**
12691 * Do either or both things: (1) change the current configuration, and (2)
12692 * make sure the given activity is running with the (now) current
12693 * configuration. Returns true if the activity has been left running, or
12694 * false if <var>starting</var> is being destroyed to match the new
12695 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012696 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697 */
12698 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012699 ActivityRecord starting, boolean persistent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012700 int changes = 0;
12701
12702 boolean kept = true;
12703
12704 if (values != null) {
12705 Configuration newConfig = new Configuration(mConfiguration);
12706 changes = newConfig.updateFrom(values);
12707 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012708 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012709 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012710 }
12711
Doug Zongker2bec3d42009-12-04 12:52:44 -080012712 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012713
12714 if (values.locale != null) {
12715 saveLocaleLocked(values.locale,
12716 !values.locale.equals(mConfiguration.locale),
12717 values.userSetLocale);
12718 }
12719
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012720 mConfigurationSeq++;
12721 if (mConfigurationSeq <= 0) {
12722 mConfigurationSeq = 1;
12723 }
12724 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012725 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012726 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012727
12728 AttributeCache ac = AttributeCache.instance();
12729 if (ac != null) {
12730 ac.updateConfiguration(mConfiguration);
12731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012732
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012733 // Make sure all resources in our process are updated
12734 // right now, so that anyone who is going to retrieve
12735 // resource values after we return will be sure to get
12736 // the new ones. This is especially important during
12737 // boot, where the first config change needs to guarantee
12738 // all resources have that config before following boot
12739 // code is executed.
12740 mSystemThread.applyConfigurationToResources(newConfig);
12741
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012742 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012743 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
12744 msg.obj = new Configuration(mConfiguration);
12745 mHandler.sendMessage(msg);
12746 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012747
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012748 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12749 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012750 try {
12751 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012752 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012753 + app.processName + " new config " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012754 app.thread.scheduleConfigurationChanged(mConfiguration);
12755 }
12756 } catch (Exception e) {
12757 }
12758 }
12759 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012760 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12761 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
12763 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012764 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12765 broadcastIntentLocked(null, null,
12766 new Intent(Intent.ACTION_LOCALE_CHANGED),
12767 null, null, 0, null, null,
12768 null, false, false, MY_PID, Process.SYSTEM_UID);
12769 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012770 }
12771 }
12772
12773 if (changes != 0 && starting == null) {
12774 // If the configuration changed, and the caller is not already
12775 // in the process of starting an activity, then find the top
12776 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012777 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012778 }
12779
12780 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012781 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012782 // And we need to make sure at this point that all other activities
12783 // are made visible with the correct configuration.
12784 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012785 }
12786
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012787 if (values != null && mWindowManager != null) {
12788 mWindowManager.setNewConfiguration(mConfiguration);
12789 }
12790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012791 return kept;
12792 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012793
12794 /**
12795 * Save the locale. You must be inside a synchronized (this) block.
12796 */
12797 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12798 if(isDiff) {
12799 SystemProperties.set("user.language", l.getLanguage());
12800 SystemProperties.set("user.region", l.getCountry());
12801 }
12802
12803 if(isPersist) {
12804 SystemProperties.set("persist.sys.language", l.getLanguage());
12805 SystemProperties.set("persist.sys.country", l.getCountry());
12806 SystemProperties.set("persist.sys.localevar", l.getVariant());
12807 }
12808 }
12809
12810 // =========================================================
12811 // LIFETIME MANAGEMENT
12812 // =========================================================
12813
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012814 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
12815 ProcessRecord TOP_APP, boolean recursed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012816 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012817 // This adjustment has already been computed. If we are calling
12818 // from the top, we may have already computed our adjustment with
12819 // an earlier hidden adjustment that isn't really for us... if
12820 // so, use the new hidden adjustment.
12821 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012822 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012823 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012824 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012825 }
12826
12827 if (app.thread == null) {
12828 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012829 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012830 return (app.curAdj=ProcessList.EMPTY_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012831 }
12832
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012833 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12834 app.adjSource = null;
12835 app.adjTarget = null;
12836 app.empty = false;
12837 app.hidden = false;
12838
12839 final int activitiesSize = app.activities.size();
12840
Dianne Hackborn7d608422011-08-07 16:24:18 -070012841 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012842 // The max adjustment doesn't allow this app to be anything
12843 // below foreground, so it is not worth doing work for it.
12844 app.adjType = "fixed";
12845 app.adjSeq = mAdjSeq;
12846 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012847 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012848 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012849 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012850 // System process can do UI, and when they do we want to have
12851 // them trim their memory after the user leaves the UI. To
12852 // facilitate this, here we need to determine whether or not it
12853 // is currently showing UI.
12854 app.systemNoUi = true;
12855 if (app == TOP_APP) {
12856 app.systemNoUi = false;
12857 } else if (activitiesSize > 0) {
12858 for (int j = 0; j < activitiesSize; j++) {
12859 final ActivityRecord r = app.activities.get(j);
12860 if (r.visible) {
12861 app.systemNoUi = false;
12862 break;
12863 }
12864 }
12865 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012866 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012867 }
12868
12869 final boolean hadForegroundActivities = app.foregroundActivities;
12870
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012871 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012872 app.keeping = false;
12873 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012874
The Android Open Source Project4df24232009-03-05 14:34:35 -080012875 // Determine the importance of the process, starting with most
12876 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012877 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012878 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012879 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012880 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012881 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012882 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012883 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012884 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012885 } else if (app.instrumentationClass != null) {
12886 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012887 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012888 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012889 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012890 } else if (app.curReceiver != null ||
12891 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
12892 // An app that is currently receiving a broadcast also
12893 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012894 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012895 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012896 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012897 } else if (app.executingServices.size() > 0) {
12898 // An app that is currently executing a service callback also
12899 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012900 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012901 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012902 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012903 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012904 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012905 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012906 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012907 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012908 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012909 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012910 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012911 // A very not-needed process. If this is lower in the lru list,
12912 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012913 adj = hiddenAdj;
12914 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012915 app.hidden = true;
12916 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012917 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012918 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012919
12920 // Examine all activities if not already foreground.
12921 if (!app.foregroundActivities && activitiesSize > 0) {
12922 for (int j = 0; j < activitiesSize; j++) {
12923 final ActivityRecord r = app.activities.get(j);
12924 if (r.visible) {
12925 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012926 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12927 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012928 app.adjType = "visible";
12929 }
12930 schedGroup = Process.THREAD_GROUP_DEFAULT;
12931 app.hidden = false;
12932 app.foregroundActivities = true;
12933 break;
12934 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
12935 || r.state == ActivityState.STOPPING) {
12936 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012937 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12938 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012939 app.adjType = "stopping";
12940 }
12941 app.foregroundActivities = true;
12942 }
12943 }
12944 }
12945
Dianne Hackborn7d608422011-08-07 16:24:18 -070012946 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012947 if (app.foregroundServices) {
12948 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012949 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012950 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012951 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012952 } else if (app.forcingToForeground != null) {
12953 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012954 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012955 app.adjType = "force-foreground";
12956 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012957 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012958 }
12959 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012960
Dianne Hackborn7d608422011-08-07 16:24:18 -070012961 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012962 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012963 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012964 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12965 app.adjType = "heavy";
12966 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012967
Dianne Hackborn7d608422011-08-07 16:24:18 -070012968 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012969 // This process is hosting what we currently consider to be the
12970 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012971 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012972 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12973 app.adjType = "home";
12974 }
12975
Joe Onorato8a9b2202010-02-26 18:56:32 -080012976 //Slog.i(TAG, "OOM " + app + ": initial adj=" + adj);
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012977
The Android Open Source Project4df24232009-03-05 14:34:35 -080012978 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012979 // there are applications dependent on our services or providers, but
12980 // this gives us a baseline and makes sure we don't get into an
12981 // infinite recursion.
12982 app.adjSeq = mAdjSeq;
12983 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012984
Christopher Tate6fa95972009-06-05 18:43:55 -070012985 if (mBackupTarget != null && app == mBackupTarget.app) {
12986 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012987 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012988 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012989 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012990 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012991 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012992 }
12993 }
12994
Dianne Hackborn7d608422011-08-07 16:24:18 -070012995 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012996 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012997 final long now = SystemClock.uptimeMillis();
12998 // This process is more important if the top activity is
12999 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013000 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013001 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013002 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013003 if (s.startRequested) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013004 if (app.hasShownUi) {
13005 // If this process has shown some UI, let it immediately
13006 // go to the LRU list because it may be pretty heavy with
13007 // UI stuff. We'll tag it with a label just to help
13008 // debug and understand what is going on.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013009 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013010 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013011 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013012 } else {
13013 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13014 // This service has seen some activity within
13015 // recent memory, so we will keep its process ahead
13016 // of the background processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013017 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
13018 adj = ProcessList.SECONDARY_SERVER_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013019 app.adjType = "started-services";
13020 app.hidden = false;
13021 }
13022 }
13023 // If we have let the service slide into the background
13024 // state, still have some text describing what it is doing
13025 // even though the service no longer has an impact.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013026 if (adj > ProcessList.SECONDARY_SERVER_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013027 app.adjType = "started-bg-services";
13028 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013029 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013030 // Don't kill this process because it is doing work; it
13031 // has said it is doing work.
13032 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013033 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013034 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013035 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013036 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013037 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013038 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013039 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013040 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013041 // XXX should compute this based on the max of
13042 // all connected clients.
13043 ConnectionRecord cr = clist.get(i);
13044 if (cr.binding.client == app) {
13045 // Binding to ourself is not interesting.
13046 continue;
13047 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013048 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013049 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013050 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013051 int myHiddenAdj = hiddenAdj;
13052 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013053 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013054 myHiddenAdj = client.hiddenAdj;
13055 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013056 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013057 }
13058 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013059 clientAdj = computeOomAdjLocked(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013060 client, myHiddenAdj, TOP_APP, true);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013061 String adjType = null;
13062 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13063 // Not doing bind OOM management, so treat
13064 // this guy more like a started service.
13065 if (app.hasShownUi) {
13066 // If this process has shown some UI, let it immediately
13067 // go to the LRU list because it may be pretty heavy with
13068 // UI stuff. We'll tag it with a label just to help
13069 // debug and understand what is going on.
13070 if (adj > clientAdj) {
13071 adjType = "bound-bg-ui-services";
13072 }
13073 clientAdj = adj;
13074 } else {
13075 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13076 // This service has not seen activity within
13077 // recent memory, so allow it to drop to the
13078 // LRU list if there is no other reason to keep
13079 // it around. We'll also tag it with a label just
13080 // to help debug and undertand what is going on.
13081 if (adj > clientAdj) {
13082 adjType = "bound-bg-services";
13083 }
13084 clientAdj = adj;
13085 }
13086 }
13087 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013088 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013089 // If this process has recently shown UI, and
13090 // the process that is binding to it is less
13091 // important than being visible, then we don't
13092 // care about the binding as much as we care
13093 // about letting this process get into the LRU
13094 // list to be killed and restarted if needed for
13095 // memory.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013096 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013097 adjType = "bound-bg-ui-services";
13098 } else {
13099 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13100 |Context.BIND_IMPORTANT)) != 0) {
13101 adj = clientAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013102 } else if (clientAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013103 adj = clientAdj;
13104 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013105 adj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013106 }
13107 if (!client.hidden) {
13108 app.hidden = false;
13109 }
13110 if (client.keeping) {
13111 app.keeping = true;
13112 }
13113 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013114 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013115 }
13116 if (adjType != null) {
13117 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013118 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13119 .REASON_SERVICE_IN_USE;
13120 app.adjSource = cr.binding.client;
13121 app.adjTarget = s.name;
13122 }
13123 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13124 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13125 schedGroup = Process.THREAD_GROUP_DEFAULT;
13126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013127 }
13128 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013129 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13130 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013131 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013132 (a.visible || a.state == ActivityState.RESUMED
13133 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013134 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013135 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13136 schedGroup = Process.THREAD_GROUP_DEFAULT;
13137 }
13138 app.hidden = false;
13139 app.adjType = "service";
13140 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13141 .REASON_SERVICE_IN_USE;
13142 app.adjSource = a;
13143 app.adjTarget = s.name;
13144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013145 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013146 }
13147 }
13148 }
13149 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013150
Dianne Hackborn287952c2010-09-22 22:34:31 -070013151 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013152 // would like to avoid killing it unless it would prevent the current
13153 // application from running. By default we put the process in
13154 // with the rest of the background processes; as we scan through
13155 // its services we may bump it up from there.
13156 if (adj > hiddenAdj) {
13157 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013158 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013159 app.adjType = "bg-services";
13160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013161 }
13162
Dianne Hackborn7d608422011-08-07 16:24:18 -070013163 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013164 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013165 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013166 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013167 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013168 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013169 if (cpr.clients.size() != 0) {
13170 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013171 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013172 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013173 if (client == app) {
13174 // Being our own client is not interesting.
13175 continue;
13176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013177 int myHiddenAdj = hiddenAdj;
13178 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013179 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013180 myHiddenAdj = client.hiddenAdj;
13181 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013182 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013183 }
13184 }
13185 int clientAdj = computeOomAdjLocked(
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013186 client, myHiddenAdj, TOP_APP, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013187 if (adj > clientAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013188 if (app.hasShownUi && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013189 app.adjType = "bg-ui-provider";
13190 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013191 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13192 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013193 app.adjType = "provider";
13194 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013195 if (!client.hidden) {
13196 app.hidden = false;
13197 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013198 if (client.keeping) {
13199 app.keeping = true;
13200 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013201 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13202 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013203 app.adjSource = client;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013204 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013205 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013206 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13207 schedGroup = Process.THREAD_GROUP_DEFAULT;
13208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013209 }
13210 }
13211 // If the provider has external (non-framework) process
13212 // dependencies, ensure that its adjustment is at least
13213 // FOREGROUND_APP_ADJ.
13214 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013215 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13216 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013217 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013218 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013219 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013220 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013221 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013222 }
13223 }
13224 }
13225 }
13226
13227 app.curRawAdj = adj;
13228
Joe Onorato8a9b2202010-02-26 18:56:32 -080013229 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013230 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13231 if (adj > app.maxAdj) {
13232 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013233 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013234 schedGroup = Process.THREAD_GROUP_DEFAULT;
13235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013236 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013237 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013238 app.keeping = true;
13239 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013240
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013241 if (app.hasAboveClient) {
13242 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13243 // then we need to drop its adjustment to be lower than the service's
13244 // in order to honor the request. We want to drop it by one adjustment
13245 // level... but there is special meaning applied to various levels so
13246 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013247 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013248 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013249 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13250 adj = ProcessList.VISIBLE_APP_ADJ;
13251 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13252 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13253 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13254 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
13255 } else if (adj < ProcessList.EMPTY_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013256 adj++;
13257 }
13258 }
13259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013260 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013261 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013262
13263 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013264 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13265 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013266 }
13267
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013268 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013269 }
13270
13271 /**
13272 * Ask a given process to GC right now.
13273 */
13274 final void performAppGcLocked(ProcessRecord app) {
13275 try {
13276 app.lastRequestedGc = SystemClock.uptimeMillis();
13277 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013278 if (app.reportLowMemory) {
13279 app.reportLowMemory = false;
13280 app.thread.scheduleLowMemory();
13281 } else {
13282 app.thread.processInBackground();
13283 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013284 }
13285 } catch (Exception e) {
13286 // whatever.
13287 }
13288 }
13289
13290 /**
13291 * Returns true if things are idle enough to perform GCs.
13292 */
Josh Bartel7f208742010-02-25 11:01:44 -060013293 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013294 return mParallelBroadcasts.size() == 0
13295 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013296 && (mSleeping || (mMainStack.mResumedActivity != null &&
13297 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013298 }
13299
13300 /**
13301 * Perform GCs on all processes that are waiting for it, but only
13302 * if things are idle.
13303 */
13304 final void performAppGcsLocked() {
13305 final int N = mProcessesToGc.size();
13306 if (N <= 0) {
13307 return;
13308 }
Josh Bartel7f208742010-02-25 11:01:44 -060013309 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013310 while (mProcessesToGc.size() > 0) {
13311 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013312 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013313 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13314 <= SystemClock.uptimeMillis()) {
13315 // To avoid spamming the system, we will GC processes one
13316 // at a time, waiting a few seconds between each.
13317 performAppGcLocked(proc);
13318 scheduleAppGcsLocked();
13319 return;
13320 } else {
13321 // It hasn't been long enough since we last GCed this
13322 // process... put it in the list to wait for its time.
13323 addProcessToGcListLocked(proc);
13324 break;
13325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013326 }
13327 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013328
13329 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013330 }
13331 }
13332
13333 /**
13334 * If all looks good, perform GCs on all processes waiting for them.
13335 */
13336 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013337 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013338 performAppGcsLocked();
13339 return;
13340 }
13341 // Still not idle, wait some more.
13342 scheduleAppGcsLocked();
13343 }
13344
13345 /**
13346 * Schedule the execution of all pending app GCs.
13347 */
13348 final void scheduleAppGcsLocked() {
13349 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013350
13351 if (mProcessesToGc.size() > 0) {
13352 // Schedule a GC for the time to the next process.
13353 ProcessRecord proc = mProcessesToGc.get(0);
13354 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13355
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013356 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013357 long now = SystemClock.uptimeMillis();
13358 if (when < (now+GC_TIMEOUT)) {
13359 when = now + GC_TIMEOUT;
13360 }
13361 mHandler.sendMessageAtTime(msg, when);
13362 }
13363 }
13364
13365 /**
13366 * Add a process to the array of processes waiting to be GCed. Keeps the
13367 * list in sorted order by the last GC time. The process can't already be
13368 * on the list.
13369 */
13370 final void addProcessToGcListLocked(ProcessRecord proc) {
13371 boolean added = false;
13372 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13373 if (mProcessesToGc.get(i).lastRequestedGc <
13374 proc.lastRequestedGc) {
13375 added = true;
13376 mProcessesToGc.add(i+1, proc);
13377 break;
13378 }
13379 }
13380 if (!added) {
13381 mProcessesToGc.add(0, proc);
13382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013383 }
13384
13385 /**
13386 * Set up to ask a process to GC itself. This will either do it
13387 * immediately, or put it on the list of processes to gc the next
13388 * time things are idle.
13389 */
13390 final void scheduleAppGcLocked(ProcessRecord app) {
13391 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013392 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013393 return;
13394 }
13395 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013396 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013397 scheduleAppGcsLocked();
13398 }
13399 }
13400
Dianne Hackborn287952c2010-09-22 22:34:31 -070013401 final void checkExcessivePowerUsageLocked(boolean doKills) {
13402 updateCpuStatsNow();
13403
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013404 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013405 boolean doWakeKills = doKills;
13406 boolean doCpuKills = doKills;
13407 if (mLastPowerCheckRealtime == 0) {
13408 doWakeKills = false;
13409 }
13410 if (mLastPowerCheckUptime == 0) {
13411 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013412 }
13413 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013414 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013415 }
13416 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013417 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13418 final long curUptime = SystemClock.uptimeMillis();
13419 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13420 mLastPowerCheckRealtime = curRealtime;
13421 mLastPowerCheckUptime = curUptime;
13422 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13423 doWakeKills = false;
13424 }
13425 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13426 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013427 }
13428 int i = mLruProcesses.size();
13429 while (i > 0) {
13430 i--;
13431 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013432 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013433 long wtime;
13434 synchronized (stats) {
13435 wtime = stats.getProcessWakeTime(app.info.uid,
13436 app.pid, curRealtime);
13437 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013438 long wtimeUsed = wtime - app.lastWakeTime;
13439 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13440 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013441 StringBuilder sb = new StringBuilder(128);
13442 sb.append("Wake for ");
13443 app.toShortString(sb);
13444 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013445 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013446 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013447 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013448 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013449 sb.append((wtimeUsed*100)/realtimeSince);
13450 sb.append("%)");
13451 Slog.i(TAG, sb.toString());
13452 sb.setLength(0);
13453 sb.append("CPU for ");
13454 app.toShortString(sb);
13455 sb.append(": over ");
13456 TimeUtils.formatDuration(uptimeSince, sb);
13457 sb.append(" used ");
13458 TimeUtils.formatDuration(cputimeUsed, sb);
13459 sb.append(" (");
13460 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013461 sb.append("%)");
13462 Slog.i(TAG, sb.toString());
13463 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013464 // If a process has held a wake lock for more
13465 // than 50% of the time during this period,
13466 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013467 if (doWakeKills && realtimeSince > 0
13468 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13469 synchronized (stats) {
13470 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13471 realtimeSince, wtimeUsed);
13472 }
13473 Slog.w(TAG, "Excessive wake lock in " + app.processName
13474 + " (pid " + app.pid + "): held " + wtimeUsed
13475 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013476 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13477 app.processName, app.setAdj, "excessive wake lock");
13478 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013479 } else if (doCpuKills && uptimeSince > 0
13480 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13481 synchronized (stats) {
13482 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13483 uptimeSince, cputimeUsed);
13484 }
13485 Slog.w(TAG, "Excessive CPU in " + app.processName
13486 + " (pid " + app.pid + "): used " + cputimeUsed
13487 + " during " + uptimeSince);
13488 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13489 app.processName, app.setAdj, "excessive cpu");
13490 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013491 } else {
13492 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013493 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013494 }
13495 }
13496 }
13497 }
13498
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013499 private final boolean updateOomAdjLocked(
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013500 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013501 app.hiddenAdj = hiddenAdj;
13502
13503 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013504 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013505 }
13506
Dianne Hackborn287952c2010-09-22 22:34:31 -070013507 final boolean wasKeeping = app.keeping;
13508
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013509 boolean success = true;
13510
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013511 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013512
Jeff Brown10e89712011-07-08 18:52:57 -070013513 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013514 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
13515 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013516 // If this app is transitioning from foreground to
13517 // non-foreground, have it do a gc.
13518 scheduleAppGcLocked(app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013519 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13520 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Jeff Brown10e89712011-07-08 18:52:57 -070013521 // Likewise do a gc when an app is moving in to the
13522 // background (such as a service stopping).
13523 scheduleAppGcLocked(app);
13524 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013525
Jeff Brown10e89712011-07-08 18:52:57 -070013526 if (wasKeeping && !app.keeping) {
13527 // This app is no longer something we want to keep. Note
13528 // its current wake lock time to later know to kill it if
13529 // it is not behaving well.
13530 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13531 synchronized (stats) {
13532 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13533 app.pid, SystemClock.elapsedRealtime());
13534 }
13535 app.lastCpuTime = app.curCpuTime;
13536 }
13537
13538 app.setRawAdj = app.curRawAdj;
13539 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013540 if (app.curAdj != app.setAdj) {
13541 if (Process.setOomAdj(app.pid, app.curAdj)) {
Jeff Brown10e89712011-07-08 18:52:57 -070013542 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
13543 TAG, "Set app " + app.processName +
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013544 " oom adj to " + app.curAdj + " because " + app.adjType);
13545 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013546 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013547 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013548 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013549 }
13550 }
13551 if (app.setSchedGroup != app.curSchedGroup) {
13552 app.setSchedGroup = app.curSchedGroup;
13553 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13554 "Setting process group of " + app.processName
13555 + " to " + app.curSchedGroup);
13556 if (app.waitingToKill != null &&
13557 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13558 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13559 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13560 app.processName, app.setAdj, app.waitingToKill);
13561 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013562 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013563 } else {
13564 if (true) {
13565 long oldId = Binder.clearCallingIdentity();
13566 try {
13567 Process.setProcessGroup(app.pid, app.curSchedGroup);
13568 } catch (Exception e) {
13569 Slog.w(TAG, "Failed setting process group of " + app.pid
13570 + " to " + app.curSchedGroup);
13571 e.printStackTrace();
13572 } finally {
13573 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013574 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013575 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013576 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013577 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013578 app.thread.setSchedulingGroup(app.curSchedGroup);
13579 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013580 }
13581 }
13582 }
13583 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013584 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013585 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013586 }
13587
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013588 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013589 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013590 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013591 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013592 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013593 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013594 }
13595 }
13596 return resumedActivity;
13597 }
13598
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013599 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013600 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013601 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13602 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013603 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13604 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013605
13606 mAdjSeq++;
13607
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013608 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013609 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13610 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013611 if (nowHidden != wasHidden) {
13612 // Changed to/from hidden state, so apps after it in the LRU
13613 // list may also be changed.
13614 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013615 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013616 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013617 }
13618
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013619 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013620 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013621 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13622
13623 if (false) {
13624 RuntimeException e = new RuntimeException();
13625 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013626 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013627 }
13628
13629 mAdjSeq++;
13630
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013631 // Let's determine how many processes we have running vs.
13632 // how many slots we have for background processes; we may want
13633 // to put multiple processes in a slot of there are enough of
13634 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013635 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013636 int factor = (mLruProcesses.size()-4)/numSlots;
13637 if (factor < 1) factor = 1;
13638 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013639 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013640
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013641 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013642 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013643 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013644 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013645 int numBg = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013646 while (i > 0) {
13647 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013648 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013649 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013650 updateOomAdjLocked(app, curHiddenAdj, TOP_APP);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013651 if (curHiddenAdj < ProcessList.EMPTY_APP_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013652 && app.curAdj == curHiddenAdj) {
13653 step++;
13654 if (step >= factor) {
13655 step = 0;
13656 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013657 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013658 }
13659 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013660 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013661 numHidden++;
13662 if (numHidden > mProcessLimit) {
13663 Slog.i(TAG, "No longer want " + app.processName
13664 + " (pid " + app.pid + "): hidden #" + numHidden);
13665 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13666 app.processName, app.setAdj, "too many background");
13667 app.killedBackground = true;
13668 Process.killProcessQuiet(app.pid);
13669 } else {
13670 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013671 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013672 } else if (app.curAdj >= ProcessList.HOME_APP_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013673 numBg++;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013674 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013675 }
13676 }
13677
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013678 // Now determine the memory trimming level of background processes.
13679 // Unfortunately we need to start at the back of the list to do this
13680 // properly. We only do this if the number of background apps we
13681 // are managing to keep around is less than half the maximum we desire;
13682 // if we are keeping a good number around, we'll let them use whatever
13683 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013684 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013685 final int N = mLruProcesses.size();
13686 factor = numBg/3;
13687 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013688 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013689 for (i=0; i<N; i++) {
13690 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013691 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013692 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13693 try {
13694 app.thread.scheduleTrimMemory(curLevel);
13695 } catch (RemoteException e) {
13696 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013697 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013698 // For these apps we will also finish their activities
13699 // to help them free memory.
13700 mMainStack.destroyActivitiesLocked(app, false);
13701 }
13702 }
13703 app.trimMemoryLevel = curLevel;
13704 step++;
13705 if (step >= factor) {
13706 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013707 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13708 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013709 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013710 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13711 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013712 break;
13713 }
13714 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013715 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013716 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013717 && app.thread != null) {
13718 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013719 app.thread.scheduleTrimMemory(
13720 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013721 } catch (RemoteException e) {
13722 }
13723 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013724 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013725 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013726 && app.pendingUiClean) {
13727 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13728 && app.thread != null) {
13729 try {
13730 app.thread.scheduleTrimMemory(
13731 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13732 } catch (RemoteException e) {
13733 }
13734 }
13735 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13736 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013737 } else {
13738 app.trimMemoryLevel = 0;
13739 }
13740 }
13741 } else {
13742 final int N = mLruProcesses.size();
13743 for (i=0; i<N; i++) {
13744 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013745 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013746 && app.pendingUiClean) {
13747 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13748 && app.thread != null) {
13749 try {
13750 app.thread.scheduleTrimMemory(
13751 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13752 } catch (RemoteException e) {
13753 }
13754 }
13755 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13756 app.pendingUiClean = false;
13757 } else {
13758 app.trimMemoryLevel = 0;
13759 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013760 }
13761 }
13762
13763 if (mAlwaysFinishActivities) {
13764 mMainStack.destroyActivitiesLocked(null, false);
13765 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013766 }
13767
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013768 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013769 synchronized (this) {
13770 int i;
13771
13772 // First remove any unused application processes whose package
13773 // has been removed.
13774 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13775 final ProcessRecord app = mRemovedProcesses.get(i);
13776 if (app.activities.size() == 0
13777 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013778 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013779 TAG, "Exiting empty application process "
13780 + app.processName + " ("
13781 + (app.thread != null ? app.thread.asBinder() : null)
13782 + ")\n");
13783 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013784 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13785 app.processName, app.setAdj, "empty");
13786 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013787 } else {
13788 try {
13789 app.thread.scheduleExit();
13790 } catch (Exception e) {
13791 // Ignore exceptions.
13792 }
13793 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013794 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013795 mRemovedProcesses.remove(i);
13796
13797 if (app.persistent) {
13798 if (app.persistent) {
13799 addAppLocked(app.info);
13800 }
13801 }
13802 }
13803 }
13804
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013805 // Now update the oom adj for all processes.
13806 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013807 }
13808 }
13809
13810 /** This method sends the specified signal to each of the persistent apps */
13811 public void signalPersistentProcesses(int sig) throws RemoteException {
13812 if (sig != Process.SIGNAL_USR1) {
13813 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13814 }
13815
13816 synchronized (this) {
13817 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13818 != PackageManager.PERMISSION_GRANTED) {
13819 throw new SecurityException("Requires permission "
13820 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13821 }
13822
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013823 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13824 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013825 if (r.thread != null && r.persistent) {
13826 Process.sendSignal(r.pid, sig);
13827 }
13828 }
13829 }
13830 }
13831
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013832 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13833 if (proc == null || proc == mProfileProc) {
13834 proc = mProfileProc;
13835 path = mProfileFile;
13836 profileType = mProfileType;
13837 clearProfilerLocked();
13838 }
13839 if (proc == null) {
13840 return;
13841 }
13842 try {
13843 proc.thread.profilerControl(false, path, null, profileType);
13844 } catch (RemoteException e) {
13845 throw new IllegalStateException("Process disappeared");
13846 }
13847 }
13848
13849 private void clearProfilerLocked() {
13850 if (mProfileFd != null) {
13851 try {
13852 mProfileFd.close();
13853 } catch (IOException e) {
13854 }
13855 }
13856 mProfileApp = null;
13857 mProfileProc = null;
13858 mProfileFile = null;
13859 mProfileType = 0;
13860 mAutoStopProfiler = false;
13861 }
13862
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013863 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013864 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013865
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013866 try {
13867 synchronized (this) {
13868 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13869 // its own permission.
13870 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13871 != PackageManager.PERMISSION_GRANTED) {
13872 throw new SecurityException("Requires permission "
13873 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013874 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013875
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013876 if (start && fd == null) {
13877 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013878 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013879
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013880 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013881 if (process != null) {
13882 try {
13883 int pid = Integer.parseInt(process);
13884 synchronized (mPidsSelfLocked) {
13885 proc = mPidsSelfLocked.get(pid);
13886 }
13887 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013888 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013889
13890 if (proc == null) {
13891 HashMap<String, SparseArray<ProcessRecord>> all
13892 = mProcessNames.getMap();
13893 SparseArray<ProcessRecord> procs = all.get(process);
13894 if (procs != null && procs.size() > 0) {
13895 proc = procs.valueAt(0);
13896 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013897 }
13898 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013899
13900 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013901 throw new IllegalArgumentException("Unknown process: " + process);
13902 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013903
13904 if (start) {
13905 stopProfilerLocked(null, null, 0);
13906 setProfileApp(proc.info, proc.processName, path, fd, false);
13907 mProfileProc = proc;
13908 mProfileType = profileType;
13909 try {
13910 fd = fd.dup();
13911 } catch (IOException e) {
13912 fd = null;
13913 }
13914 proc.thread.profilerControl(start, path, fd, profileType);
13915 fd = null;
13916 mProfileFd = null;
13917 } else {
13918 stopProfilerLocked(proc, path, profileType);
13919 if (fd != null) {
13920 try {
13921 fd.close();
13922 } catch (IOException e) {
13923 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013924 }
13925 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013926
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013927 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013928 }
13929 } catch (RemoteException e) {
13930 throw new IllegalStateException("Process disappeared");
13931 } finally {
13932 if (fd != null) {
13933 try {
13934 fd.close();
13935 } catch (IOException e) {
13936 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013937 }
13938 }
13939 }
Andy McFadden824c5102010-07-09 16:26:57 -070013940
13941 public boolean dumpHeap(String process, boolean managed,
13942 String path, ParcelFileDescriptor fd) throws RemoteException {
13943
13944 try {
13945 synchronized (this) {
13946 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13947 // its own permission (same as profileControl).
13948 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13949 != PackageManager.PERMISSION_GRANTED) {
13950 throw new SecurityException("Requires permission "
13951 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13952 }
13953
13954 if (fd == null) {
13955 throw new IllegalArgumentException("null fd");
13956 }
13957
13958 ProcessRecord proc = null;
13959 try {
13960 int pid = Integer.parseInt(process);
13961 synchronized (mPidsSelfLocked) {
13962 proc = mPidsSelfLocked.get(pid);
13963 }
13964 } catch (NumberFormatException e) {
13965 }
13966
13967 if (proc == null) {
13968 HashMap<String, SparseArray<ProcessRecord>> all
13969 = mProcessNames.getMap();
13970 SparseArray<ProcessRecord> procs = all.get(process);
13971 if (procs != null && procs.size() > 0) {
13972 proc = procs.valueAt(0);
13973 }
13974 }
13975
13976 if (proc == null || proc.thread == null) {
13977 throw new IllegalArgumentException("Unknown process: " + process);
13978 }
13979
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013980 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13981 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013982 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13983 throw new SecurityException("Process not debuggable: " + proc);
13984 }
13985 }
13986
13987 proc.thread.dumpHeap(managed, path, fd);
13988 fd = null;
13989 return true;
13990 }
13991 } catch (RemoteException e) {
13992 throw new IllegalStateException("Process disappeared");
13993 } finally {
13994 if (fd != null) {
13995 try {
13996 fd.close();
13997 } catch (IOException e) {
13998 }
13999 }
14000 }
14001 }
14002
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014003 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14004 public void monitor() {
14005 synchronized (this) { }
14006 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014007
14008 public void onCoreSettingsChange(Bundle settings) {
14009 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14010 ProcessRecord processRecord = mLruProcesses.get(i);
14011 try {
14012 if (processRecord.thread != null) {
14013 processRecord.thread.setCoreSettings(settings);
14014 }
14015 } catch (RemoteException re) {
14016 /* ignore */
14017 }
14018 }
14019 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014020
14021 // Multi-user methods
14022
14023 public boolean switchUser(int userid) {
14024 // TODO
14025 return true;
14026 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014027}