blob: 15ef056ee255c501150593bef9d192eb4518df76 [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;
Dianne Hackborn905577f2011-09-07 18:31:28 -0700109import android.util.Pair;
Joe Onorato8a9b2202010-02-26 18:56:32 -0800110import android.util.Slog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800111import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.util.PrintWriterPrinter;
113import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700114import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.view.Gravity;
116import android.view.LayoutInflater;
117import android.view.View;
118import android.view.WindowManager;
119import android.view.WindowManagerPolicy;
120
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700121import java.io.BufferedInputStream;
122import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700123import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700124import java.io.DataInputStream;
125import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import java.io.File;
127import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700128import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700130import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200131import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800132import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700134import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135import java.lang.IllegalStateException;
136import java.lang.ref.WeakReference;
137import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700138import java.util.Collections;
139import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140import java.util.HashMap;
141import java.util.HashSet;
142import java.util.Iterator;
143import java.util.List;
144import java.util.Locale;
145import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700146import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700147import java.util.concurrent.atomic.AtomicBoolean;
148import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700150public final class ActivityManagerService extends ActivityManagerNative
151 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 static final String TAG = "ActivityManager";
153 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400154 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 static final boolean DEBUG_SWITCH = localLOGV || false;
156 static final boolean DEBUG_TASKS = localLOGV || false;
157 static final boolean DEBUG_PAUSE = localLOGV || false;
158 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
159 static final boolean DEBUG_TRANSITION = localLOGV || false;
160 static final boolean DEBUG_BROADCAST = localLOGV || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700161 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700163 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final boolean DEBUG_VISBILITY = localLOGV || false;
165 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700166 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800167 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700169 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700170 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700171 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700172 static final boolean DEBUG_POWER = localLOGV || false;
173 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final boolean VALIDATE_TOKENS = false;
175 static final boolean SHOW_ACTIVITY_START_TIME = true;
176
177 // Control over CPU and battery monitoring.
178 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
179 static final boolean MONITOR_CPU_USAGE = true;
180 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
181 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
182 static final boolean MONITOR_THREAD_CPU_USAGE = false;
183
Dianne Hackborn1655be42009-05-08 14:29:01 -0700184 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700185 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700186
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800187 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800189 // Maximum number of recent tasks that we can remember.
190 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700191
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700192 // Amount of time after a call to stopAppSwitches() during which we will
193 // prevent further untrusted switches from happening.
194 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195
196 // How long we wait for a launched process to attach to the activity manager
197 // before we decide it's never going to come up for real.
198 static final int PROC_START_TIMEOUT = 10*1000;
199
Jeff Brown3f9dd282011-07-08 20:02:19 -0700200 // How long we wait for a launched process to attach to the activity manager
201 // before we decide it's never going to come up for real, when the process was
202 // started with a wrapper for instrumentation (such as Valgrind) because it
203 // could take much longer than usual.
204 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 // How long to wait after going idle before forcing apps to GC.
207 static final int GC_TIMEOUT = 5*1000;
208
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700209 // The minimum amount of time between successive GC requests for a process.
210 static final int GC_MIN_INTERVAL = 60*1000;
211
Dianne Hackborn287952c2010-09-22 22:34:31 -0700212 // The rate at which we check for apps using excessive power -- 15 mins.
213 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
214
215 // The minimum sample duration we will allow before deciding we have
216 // enough data on wake locks to start killing things.
217 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
218
219 // The minimum sample duration we will allow before deciding we have
220 // enough data on CPU usage to start killing things.
221 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700222
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 // How long we allow a receiver to run before giving up on it.
224 static final int BROADCAST_TIMEOUT = 10*1000;
225
226 // How long we wait for a service to finish executing.
227 static final int SERVICE_TIMEOUT = 20*1000;
228
229 // How long a service needs to be running until restarting its process
230 // is no longer considered to be a relaunch of the service.
231 static final int SERVICE_RESTART_DURATION = 5*1000;
232
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700233 // How long a service needs to be running until it will start back at
234 // SERVICE_RESTART_DURATION after being killed.
235 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
236
237 // Multiplying factor to increase restart duration time by, for each time
238 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
239 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
240
241 // The minimum amount of time between restarting services that we allow.
242 // That is, when multiple services are restarting, we won't allow each
243 // to restart less than this amount of time from the last one.
244 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 // Maximum amount of time for there to be no activity on a service before
247 // we consider it non-essential and allow its process to go on the
248 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700249 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
251 // How long we wait until we timeout on key dispatching.
252 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 // How long we wait until we timeout on key dispatching during instrumentation.
255 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
256
Dan Egnor42471dd2010-01-07 17:25:22 -0800257 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258
259 static final String[] EMPTY_STRING_ARRAY = new String[0];
260
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700261 public ActivityStack mMainStack;
262
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700264 * Description of a request to start a new activity, which has been held
265 * due to app switches being disabled.
266 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700267 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700268 ActivityRecord r;
269 ActivityRecord sourceRecord;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700270 Uri[] grantedUriPermissions;
271 int grantedMode;
272 boolean onlyIfNeeded;
273 }
274
275 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
276 = new ArrayList<PendingActivityLaunch>();
277
278 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 * List of all active broadcasts that are to be executed immediately
280 * (without waiting for another broadcast to finish). Currently this only
281 * contains broadcasts to registered receivers, to avoid spinning up
282 * a bunch of processes to execute IntentReceiver components.
283 */
284 final ArrayList<BroadcastRecord> mParallelBroadcasts
285 = new ArrayList<BroadcastRecord>();
286
287 /**
288 * List of all active broadcasts that are to be executed one at a time.
289 * The object at the top of the list is the currently activity broadcasts;
290 * those after it are waiting for the top to finish..
291 */
292 final ArrayList<BroadcastRecord> mOrderedBroadcasts
293 = new ArrayList<BroadcastRecord>();
294
295 /**
Dianne Hackborn12527f92009-11-11 17:39:50 -0800296 * Historical data of past broadcasts, for debugging.
297 */
Dianne Hackborn28695e02011-11-02 21:59:51 -0700298 static final int MAX_BROADCAST_HISTORY = 25;
Dianne Hackborn12527f92009-11-11 17:39:50 -0800299 final BroadcastRecord[] mBroadcastHistory
300 = new BroadcastRecord[MAX_BROADCAST_HISTORY];
301
302 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 * Set when we current have a BROADCAST_INTENT_MSG in flight.
304 */
305 boolean mBroadcastsScheduled = false;
306
307 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800308 * Activity we have told the window manager to have key focus.
309 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700310 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700311 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312 * List of intents that were used to start the most recent tasks.
313 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700314 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315
316 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700317 * Process management.
318 */
319 final ProcessList mProcessList = new ProcessList();
320
321 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 * All of the applications we currently have running organized by name.
323 * The keys are strings of the application package name (as
324 * returned by the package manager), and the keys are ApplicationRecord
325 * objects.
326 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700327 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328
329 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700330 * The currently running heavy-weight process, if any.
331 */
332 ProcessRecord mHeavyWeightProcess = null;
333
334 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 * The last time that various processes have crashed.
336 */
337 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
338
339 /**
340 * Set of applications that we consider to be bad, and will reject
341 * incoming broadcasts from (which the user has no control over).
342 * Processes are added to this set when they have crashed twice within
343 * a minimum amount of time; they are removed from it when they are
344 * later restarted (hopefully due to some user action). The value is the
345 * time it was added to the list.
346 */
347 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
348
349 /**
350 * All of the processes we currently have running organized by pid.
351 * The keys are the pid running the application.
352 *
353 * <p>NOTE: This object is protected by its own lock, NOT the global
354 * activity manager lock!
355 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700356 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357
358 /**
359 * All of the processes that have been forced to be foreground. The key
360 * is the pid of the caller who requested it (we hold a death
361 * link on it).
362 */
363 abstract class ForegroundToken implements IBinder.DeathRecipient {
364 int pid;
365 IBinder token;
366 }
367 final SparseArray<ForegroundToken> mForegroundProcesses
368 = new SparseArray<ForegroundToken>();
369
370 /**
371 * List of records for processes that someone had tried to start before the
372 * system was ready. We don't start them at that point, but ensure they
373 * are started by the time booting is complete.
374 */
375 final ArrayList<ProcessRecord> mProcessesOnHold
376 = new ArrayList<ProcessRecord>();
377
378 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 * List of persistent applications that are in the process
380 * of being started.
381 */
382 final ArrayList<ProcessRecord> mPersistentStartingProcesses
383 = new ArrayList<ProcessRecord>();
384
385 /**
386 * Processes that are being forcibly torn down.
387 */
388 final ArrayList<ProcessRecord> mRemovedProcesses
389 = new ArrayList<ProcessRecord>();
390
391 /**
392 * List of running applications, sorted by recent usage.
393 * The first entry in the list is the least recently used.
394 * It contains ApplicationRecord objects. This list does NOT include
395 * any persistent application records (since we never want to exit them).
396 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800397 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800398 = new ArrayList<ProcessRecord>();
399
400 /**
401 * List of processes that should gc as soon as things are idle.
402 */
403 final ArrayList<ProcessRecord> mProcessesToGc
404 = new ArrayList<ProcessRecord>();
405
406 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800407 * This is the process holding what we currently consider to be
408 * the "home" activity.
409 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700410 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800411
412 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700413 * This is the process holding the activity the user last visited that
414 * is in a different process from the one they are currently in.
415 */
416 ProcessRecord mPreviousProcess;
417
418 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400419 * Packages that the user has asked to have run in screen size
420 * compatibility mode instead of filling the screen.
421 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700422 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400423
424 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800425 * Set of PendingResultRecord objects that are currently active.
426 */
427 final HashSet mPendingResultRecords = new HashSet();
428
429 /**
430 * Set of IntentSenderRecord objects that are currently active.
431 */
432 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
433 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
434
435 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800436 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700437 * already logged DropBox entries for. Guarded by itself. If
438 * something (rogue user app) forces this over
439 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
440 */
441 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
442 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
443
444 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700445 * Strict Mode background batched logging state.
446 *
447 * The string buffer is guarded by itself, and its lock is also
448 * used to determine if another batched write is already
449 * in-flight.
450 */
451 private final StringBuilder mStrictModeBuffer = new StringBuilder();
452
453 /**
Jeff Brown4d94a762010-09-23 11:33:28 -0700454 * True if we have a pending unexpired BROADCAST_TIMEOUT_MSG posted to our handler.
455 */
456 private boolean mPendingBroadcastTimeoutMessage;
457
458 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800459 * Intent broadcast that we have tried to start, but are
460 * waiting for its application's process to be created. We only
461 * need one (instead of a list) because we always process broadcasts
462 * one at a time, so no others can be started while waiting for this
463 * one.
464 */
465 BroadcastRecord mPendingBroadcast = null;
466
467 /**
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700468 * The receiver index that is pending, to restart the broadcast if needed.
469 */
470 int mPendingBroadcastRecvIndex;
471
472 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 * Keeps track of all IIntentReceivers that have been registered for
474 * broadcasts. Hash keys are the receiver IBinder, hash value is
475 * a ReceiverList.
476 */
477 final HashMap mRegisteredReceivers = new HashMap();
478
479 /**
480 * Resolver for broadcast intents to registered receivers.
481 * Holds BroadcastFilter (subclass of IntentFilter).
482 */
483 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
484 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
485 @Override
486 protected boolean allowFilterResult(
487 BroadcastFilter filter, List<BroadcastFilter> dest) {
488 IBinder target = filter.receiverList.receiver.asBinder();
489 for (int i=dest.size()-1; i>=0; i--) {
490 if (dest.get(i).receiverList.receiver.asBinder() == target) {
491 return false;
492 }
493 }
494 return true;
495 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700496
497 @Override
498 protected String packageForFilter(BroadcastFilter filter) {
499 return filter.packageName;
500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 };
502
503 /**
504 * State of all active sticky broadcasts. Keys are the action of the
505 * sticky Intent, values are an ArrayList of all broadcasted intents with
506 * that action (which should usually be one).
507 */
508 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
509 new HashMap<String, ArrayList<Intent>>();
510
511 /**
512 * All currently running services.
513 */
514 final HashMap<ComponentName, ServiceRecord> mServices =
515 new HashMap<ComponentName, ServiceRecord>();
516
517 /**
518 * All currently running services indexed by the Intent used to start them.
519 */
520 final HashMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent =
521 new HashMap<Intent.FilterComparison, ServiceRecord>();
522
523 /**
524 * All currently bound service connections. Keys are the IBinder of
525 * the client's IServiceConnection.
526 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700527 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
528 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800529
530 /**
531 * List of services that we have been asked to start,
532 * but haven't yet been able to. It is used to hold start requests
533 * while waiting for their corresponding application thread to get
534 * going.
535 */
536 final ArrayList<ServiceRecord> mPendingServices
537 = new ArrayList<ServiceRecord>();
538
539 /**
540 * List of services that are scheduled to restart following a crash.
541 */
542 final ArrayList<ServiceRecord> mRestartingServices
543 = new ArrayList<ServiceRecord>();
544
545 /**
546 * List of services that are in the process of being stopped.
547 */
548 final ArrayList<ServiceRecord> mStoppingServices
549 = new ArrayList<ServiceRecord>();
550
551 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700552 * Backup/restore process management
553 */
554 String mBackupAppName = null;
555 BackupRecord mBackupTarget = null;
556
557 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800558 * List of PendingThumbnailsRecord objects of clients who are still
559 * waiting to receive all of the thumbnails for a task.
560 */
561 final ArrayList mPendingThumbnails = new ArrayList();
562
563 /**
564 * List of HistoryRecord objects that have been finished and must
565 * still report back to a pending thumbnail receiver.
566 */
567 final ArrayList mCancelledThumbnails = new ArrayList();
568
569 /**
570 * All of the currently running global content providers. Keys are a
571 * string containing the provider name and values are a
572 * ContentProviderRecord object containing the data about it. Note
573 * that a single provider may be published under multiple names, so
574 * there may be multiple entries here for a single one in mProvidersByClass.
575 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700576 final HashMap<String, ContentProviderRecord> mProvidersByName
577 = new HashMap<String, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578
579 /**
580 * All of the currently running global content providers. Keys are a
581 * string containing the provider's implementation class and values are a
582 * ContentProviderRecord object containing the data about it.
583 */
Dianne Hackborn1c9b2602011-08-19 14:08:43 -0700584 final HashMap<ComponentName, ContentProviderRecord> mProvidersByClass
585 = new HashMap<ComponentName, ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 /**
588 * List of content providers who have clients waiting for them. The
589 * application is currently being launched and the provider will be
590 * removed from this list once it is published.
591 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700592 final ArrayList<ContentProviderRecord> mLaunchingProviders
593 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594
595 /**
596 * Global set of specific Uri permissions that have been granted.
597 */
598 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
599 = new SparseArray<HashMap<Uri, UriPermission>>();
600
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800601 CoreSettingsObserver mCoreSettingsObserver;
602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 /**
604 * Thread-local storage used to carry caller permissions over through
605 * indirect content-provider access.
606 * @see #ActivityManagerService.openContentUri()
607 */
608 private class Identity {
609 public int pid;
610 public int uid;
611
612 Identity(int _pid, int _uid) {
613 pid = _pid;
614 uid = _uid;
615 }
616 }
617 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
618
619 /**
620 * All information we have collected about the runtime performance of
621 * any user id that can impact battery performance.
622 */
623 final BatteryStatsService mBatteryStatsService;
624
625 /**
626 * information about component usage
627 */
628 final UsageStatsService mUsageStatsService;
629
630 /**
631 * Current configuration information. HistoryRecord objects are given
632 * a reference to this object to indicate which configuration they are
633 * currently running in, so this object must be kept immutable.
634 */
635 Configuration mConfiguration = new Configuration();
636
637 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800638 * Current sequencing integer of the configuration, for skipping old
639 * configurations.
640 */
641 int mConfigurationSeq = 0;
642
643 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700644 * Hardware-reported OpenGLES version.
645 */
646 final int GL_ES_VERSION;
647
648 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 * List of initialization arguments to pass to all processes when binding applications to them.
650 * For example, references to the commonly used services.
651 */
652 HashMap<String, IBinder> mAppBindArgs;
653
654 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700655 * Temporary to avoid allocations. Protected by main lock.
656 */
657 final StringBuilder mStringBuilder = new StringBuilder(256);
658
659 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800660 * Used to control how we initialize the service.
661 */
662 boolean mStartRunning = false;
663 ComponentName mTopComponent;
664 String mTopAction;
665 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700666 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 boolean mSystemReady = false;
668 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700669 boolean mWaitingUpdate = false;
670 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700671 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700672 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800673
674 Context mContext;
675
676 int mFactoryTest;
677
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700678 boolean mCheckedForSetup;
679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700681 * The time at which we will allow normal application switches again,
682 * after a call to {@link #stopAppSwitches()}.
683 */
684 long mAppSwitchesAllowedTime;
685
686 /**
687 * This is set to true after the first switch after mAppSwitchesAllowedTime
688 * is set; any switches after that will clear the time.
689 */
690 boolean mDidAppSwitch;
691
692 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700693 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700694 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700695 long mLastPowerCheckRealtime;
696
697 /**
698 * Last time (in uptime) at which we checked for power usage.
699 */
700 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700701
702 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703 * Set while we are wanting to sleep, to prevent any
704 * activities from being started/resumed.
705 */
706 boolean mSleeping = false;
707
708 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700709 * Set if we are shutting down the system, similar to sleeping.
710 */
711 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712
713 /**
714 * Task identifier that activities are currently being started
715 * in. Incremented each time a new task is created.
716 * todo: Replace this with a TokenSpace class that generates non-repeating
717 * integers that won't wrap.
718 */
719 int mCurTask = 1;
720
721 /**
722 * Current sequence id for oom_adj computation traversal.
723 */
724 int mAdjSeq = 0;
725
726 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700727 * Current sequence id for process LRU updating.
728 */
729 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800730
731 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700732 * Keep track of the number of service processes we last found, to
733 * determine on the next iteration which should be B services.
734 */
735 int mNumServiceProcs = 0;
736 int mNewNumServiceProcs = 0;
737
738 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 * System monitoring: number of processes that died since the last
740 * N procs were started.
741 */
742 int[] mProcDeaths = new int[20];
743
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700744 /**
745 * This is set if we had to do a delayed dexopt of an app before launching
746 * it, to increasing the ANR timeouts in that case.
747 */
748 boolean mDidDexOpt;
749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 String mDebugApp = null;
751 boolean mWaitForDebugger = false;
752 boolean mDebugTransient = false;
753 String mOrigDebugApp = null;
754 boolean mOrigWaitForDebugger = false;
755 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700756 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700757 String mProfileApp = null;
758 ProcessRecord mProfileProc = null;
759 String mProfileFile;
760 ParcelFileDescriptor mProfileFd;
761 int mProfileType = 0;
762 boolean mAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800763
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700764 final RemoteCallbackList<IActivityWatcher> mWatchers
765 = new RemoteCallbackList<IActivityWatcher>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700766
767 final RemoteCallbackList<IProcessObserver> mProcessObservers
768 = new RemoteCallbackList<IProcessObserver>();
769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 /**
771 * Callback of last caller to {@link #requestPss}.
772 */
773 Runnable mRequestPssCallback;
774
775 /**
776 * Remaining processes for which we are waiting results from the last
777 * call to {@link #requestPss}.
778 */
779 final ArrayList<ProcessRecord> mRequestPssList
780 = new ArrayList<ProcessRecord>();
781
782 /**
783 * Runtime statistics collection thread. This object's lock is used to
784 * protect all related state.
785 */
786 final Thread mProcessStatsThread;
787
788 /**
789 * Used to collect process stats when showing not responding dialog.
790 * Protected by mProcessStatsThread.
791 */
792 final ProcessStats mProcessStats = new ProcessStats(
793 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700794 final AtomicLong mLastCpuTime = new AtomicLong(0);
795 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800797 long mLastWriteTime = 0;
798
799 /**
800 * Set to true after the system has finished booting.
801 */
802 boolean mBooted = false;
803
Dianne Hackborn7d608422011-08-07 16:24:18 -0700804 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700805 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806
807 WindowManagerService mWindowManager;
808
809 static ActivityManagerService mSelf;
810 static ActivityThread mSystemThread;
811
812 private final class AppDeathRecipient implements IBinder.DeathRecipient {
813 final ProcessRecord mApp;
814 final int mPid;
815 final IApplicationThread mAppThread;
816
817 AppDeathRecipient(ProcessRecord app, int pid,
818 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800819 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 TAG, "New death recipient " + this
821 + " for thread " + thread.asBinder());
822 mApp = app;
823 mPid = pid;
824 mAppThread = thread;
825 }
826
827 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800828 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 TAG, "Death received in " + this
830 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 synchronized(ActivityManagerService.this) {
832 appDiedLocked(mApp, mPid, mAppThread);
833 }
834 }
835 }
836
837 static final int SHOW_ERROR_MSG = 1;
838 static final int SHOW_NOT_RESPONDING_MSG = 2;
839 static final int SHOW_FACTORY_ERROR_MSG = 3;
840 static final int UPDATE_CONFIGURATION_MSG = 4;
841 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
842 static final int WAIT_FOR_DEBUGGER_MSG = 6;
843 static final int BROADCAST_INTENT_MSG = 7;
844 static final int BROADCAST_TIMEOUT_MSG = 8;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800845 static final int SERVICE_TIMEOUT_MSG = 12;
846 static final int UPDATE_TIME_ZONE = 13;
847 static final int SHOW_UID_ERROR_MSG = 14;
848 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700850 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700851 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800852 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700853 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
854 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700855 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700856 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700857 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700858 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700859 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700860 static final int DISPATCH_FOREGROUND_ACTIVITIES_CHANGED = 31;
861 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700862 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800863
864 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700865 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700866 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867
868 final Handler mHandler = new Handler() {
869 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800870 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 //}
872
873 public void handleMessage(Message msg) {
874 switch (msg.what) {
875 case SHOW_ERROR_MSG: {
876 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800877 synchronized (ActivityManagerService.this) {
878 ProcessRecord proc = (ProcessRecord)data.get("app");
879 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800880 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800881 return;
882 }
883 AppErrorResult res = (AppErrorResult) data.get("result");
Dianne Hackborn55280a92009-05-07 15:53:46 -0700884 if (!mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800885 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 d.show();
887 proc.crashDialog = d;
888 } else {
889 // The device is asleep, so just pretend that the user
890 // saw a crash dialog and hit "force quit".
891 res.set(0);
892 }
893 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700894
895 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800896 } break;
897 case SHOW_NOT_RESPONDING_MSG: {
898 synchronized (ActivityManagerService.this) {
899 HashMap data = (HashMap) msg.obj;
900 ProcessRecord proc = (ProcessRecord)data.get("app");
901 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800902 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 return;
904 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800905
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700906 Intent intent = new Intent("android.intent.action.ANR");
907 if (!mProcessesReady) {
908 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
909 }
910 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800911 null, null, 0, null, null, null,
912 false, false, MY_PID, Process.SYSTEM_UID);
913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700915 mContext, proc, (ActivityRecord)data.get("activity"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 d.show();
917 proc.anrDialog = d;
918 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700919
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700920 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700922 case SHOW_STRICT_MODE_VIOLATION_MSG: {
923 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
924 synchronized (ActivityManagerService.this) {
925 ProcessRecord proc = (ProcessRecord) data.get("app");
926 if (proc == null) {
927 Slog.e(TAG, "App not found when showing strict mode dialog.");
928 break;
929 }
930 if (proc.crashDialog != null) {
931 Slog.e(TAG, "App already has strict mode dialog: " + proc);
932 return;
933 }
934 AppErrorResult res = (AppErrorResult) data.get("result");
935 if (!mSleeping && !mShuttingDown) {
936 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
937 d.show();
938 proc.crashDialog = d;
939 } else {
940 // The device is asleep, so just pretend that the user
941 // saw a crash dialog and hit "force quit".
942 res.set(0);
943 }
944 }
945 ensureBootCompleted();
946 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 case SHOW_FACTORY_ERROR_MSG: {
948 Dialog d = new FactoryErrorDialog(
949 mContext, msg.getData().getCharSequence("msg"));
950 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700951 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 } break;
953 case UPDATE_CONFIGURATION_MSG: {
954 final ContentResolver resolver = mContext.getContentResolver();
955 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
956 } break;
957 case GC_BACKGROUND_PROCESSES_MSG: {
958 synchronized (ActivityManagerService.this) {
959 performAppGcsIfAppropriateLocked();
960 }
961 } break;
962 case WAIT_FOR_DEBUGGER_MSG: {
963 synchronized (ActivityManagerService.this) {
964 ProcessRecord app = (ProcessRecord)msg.obj;
965 if (msg.arg1 != 0) {
966 if (!app.waitedForDebugger) {
967 Dialog d = new AppWaitingForDebuggerDialog(
968 ActivityManagerService.this,
969 mContext, app);
970 app.waitDialog = d;
971 app.waitedForDebugger = true;
972 d.show();
973 }
974 } else {
975 if (app.waitDialog != null) {
976 app.waitDialog.dismiss();
977 app.waitDialog = null;
978 }
979 }
980 }
981 } break;
982 case BROADCAST_INTENT_MSG: {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800983 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 TAG, "Received BROADCAST_INTENT_MSG");
985 processNextBroadcast(true);
986 } break;
987 case BROADCAST_TIMEOUT_MSG: {
Jeff Brown4d94a762010-09-23 11:33:28 -0700988 synchronized (ActivityManagerService.this) {
989 broadcastTimeoutLocked(true);
Jeff Hamiltonacf84742010-05-25 22:10:18 -0500990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700993 if (mDidDexOpt) {
994 mDidDexOpt = false;
995 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
996 nmsg.obj = msg.obj;
997 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
998 return;
999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 serviceTimeout((ProcessRecord)msg.obj);
1001 } break;
1002 case UPDATE_TIME_ZONE: {
1003 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001004 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1005 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 if (r.thread != null) {
1007 try {
1008 r.thread.updateTimeZone();
1009 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001010 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 }
1012 }
1013 }
1014 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001015 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001016 case CLEAR_DNS_CACHE: {
1017 synchronized (ActivityManagerService.this) {
1018 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1019 ProcessRecord r = mLruProcesses.get(i);
1020 if (r.thread != null) {
1021 try {
1022 r.thread.clearDnsCache();
1023 } catch (RemoteException ex) {
1024 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1025 }
1026 }
1027 }
1028 }
1029 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001030 case UPDATE_HTTP_PROXY: {
1031 ProxyProperties proxy = (ProxyProperties)msg.obj;
1032 String host = "";
1033 String port = "";
1034 String exclList = "";
1035 if (proxy != null) {
1036 host = proxy.getHost();
1037 port = Integer.toString(proxy.getPort());
1038 exclList = proxy.getExclusionList();
1039 }
1040 synchronized (ActivityManagerService.this) {
1041 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1042 ProcessRecord r = mLruProcesses.get(i);
1043 if (r.thread != null) {
1044 try {
1045 r.thread.setHttpProxy(host, port, exclList);
1046 } catch (RemoteException ex) {
1047 Slog.w(TAG, "Failed to update http proxy for: " +
1048 r.info.processName);
1049 }
1050 }
1051 }
1052 }
1053 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 case SHOW_UID_ERROR_MSG: {
1055 // XXX This is a temporary dialog, no need to localize.
1056 AlertDialog d = new BaseErrorDialog(mContext);
1057 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1058 d.setCancelable(false);
1059 d.setTitle("System UIDs Inconsistent");
1060 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 +02001061 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1063 mUidAlert = d;
1064 d.show();
1065 } break;
1066 case IM_FEELING_LUCKY_MSG: {
1067 if (mUidAlert != null) {
1068 mUidAlert.dismiss();
1069 mUidAlert = null;
1070 }
1071 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001072 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001073 if (mDidDexOpt) {
1074 mDidDexOpt = false;
1075 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1076 nmsg.obj = msg.obj;
1077 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1078 return;
1079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001080 ProcessRecord app = (ProcessRecord)msg.obj;
1081 synchronized (ActivityManagerService.this) {
1082 processStartTimedOutLocked(app);
1083 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001084 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001085 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1086 synchronized (ActivityManagerService.this) {
1087 doPendingActivityLaunchesLocked(true);
1088 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001089 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001090 case KILL_APPLICATION_MSG: {
1091 synchronized (ActivityManagerService.this) {
1092 int uid = msg.arg1;
1093 boolean restart = (msg.arg2 == 1);
1094 String pkg = (String) msg.obj;
Christopher Tate3dacd842011-08-19 14:56:15 -07001095 forceStopPackageLocked(pkg, uid, restart, false, true, false);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001096 }
1097 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001098 case FINALIZE_PENDING_INTENT_MSG: {
1099 ((PendingIntentRecord)msg.obj).completeFinalize();
1100 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001101 case POST_HEAVY_NOTIFICATION_MSG: {
1102 INotificationManager inm = NotificationManager.getService();
1103 if (inm == null) {
1104 return;
1105 }
1106
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001107 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001108 ProcessRecord process = root.app;
1109 if (process == null) {
1110 return;
1111 }
1112
1113 try {
1114 Context context = mContext.createPackageContext(process.info.packageName, 0);
1115 String text = mContext.getString(R.string.heavy_weight_notification,
1116 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1117 Notification notification = new Notification();
1118 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1119 notification.when = 0;
1120 notification.flags = Notification.FLAG_ONGOING_EVENT;
1121 notification.tickerText = text;
1122 notification.defaults = 0; // please be quiet
1123 notification.sound = null;
1124 notification.vibrate = null;
1125 notification.setLatestEventInfo(context, text,
1126 mContext.getText(R.string.heavy_weight_notification_detail),
1127 PendingIntent.getActivity(mContext, 0, root.intent,
1128 PendingIntent.FLAG_CANCEL_CURRENT));
1129
1130 try {
1131 int[] outId = new int[1];
1132 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1133 notification, outId);
1134 } catch (RuntimeException e) {
1135 Slog.w(ActivityManagerService.TAG,
1136 "Error showing notification for heavy-weight app", e);
1137 } catch (RemoteException e) {
1138 }
1139 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001140 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001141 }
1142 } break;
1143 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1144 INotificationManager inm = NotificationManager.getService();
1145 if (inm == null) {
1146 return;
1147 }
1148 try {
1149 inm.cancelNotification("android",
1150 R.string.heavy_weight_notification);
1151 } catch (RuntimeException e) {
1152 Slog.w(ActivityManagerService.TAG,
1153 "Error canceling notification for service", e);
1154 } catch (RemoteException e) {
1155 }
1156 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001157 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1158 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001159 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001160 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001161 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1162 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001163 }
1164 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001165 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1166 synchronized (ActivityManagerService.this) {
1167 ActivityRecord ar = (ActivityRecord)msg.obj;
1168 if (mCompatModeDialog != null) {
1169 if (mCompatModeDialog.mAppInfo.packageName.equals(
1170 ar.info.applicationInfo.packageName)) {
1171 return;
1172 }
1173 mCompatModeDialog.dismiss();
1174 mCompatModeDialog = null;
1175 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001176 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001177 if (mCompatModePackages.getPackageAskCompatModeLocked(
1178 ar.packageName)) {
1179 int mode = mCompatModePackages.computeCompatModeLocked(
1180 ar.info.applicationInfo);
1181 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1182 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1183 mCompatModeDialog = new CompatModeDialog(
1184 ActivityManagerService.this, mContext,
1185 ar.info.applicationInfo);
1186 mCompatModeDialog.show();
1187 }
1188 }
1189 }
1190 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001191 break;
1192 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001193 case DISPATCH_FOREGROUND_ACTIVITIES_CHANGED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001194 final int pid = msg.arg1;
1195 final int uid = msg.arg2;
1196 final boolean foregroundActivities = (Boolean) msg.obj;
1197 dispatchForegroundActivitiesChanged(pid, uid, foregroundActivities);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001198 break;
1199 }
1200 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001201 final int pid = msg.arg1;
1202 final int uid = msg.arg2;
1203 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001204 break;
1205 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001206 case REPORT_MEM_USAGE: {
1207 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1208 if (!isDebuggable) {
1209 return;
1210 }
1211 synchronized (ActivityManagerService.this) {
1212 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001213 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1214 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001215 // avoid spamming.
1216 return;
1217 }
1218 mLastMemUsageReportTime = now;
1219 }
1220 Thread thread = new Thread() {
1221 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001222 StringBuilder dropBuilder = new StringBuilder(1024);
1223 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001224 StringWriter oomSw = new StringWriter();
1225 PrintWriter oomPw = new PrintWriter(oomSw);
1226 StringWriter catSw = new StringWriter();
1227 PrintWriter catPw = new PrintWriter(catSw);
1228 String[] emptyArgs = new String[] { };
1229 StringBuilder tag = new StringBuilder(128);
1230 StringBuilder stack = new StringBuilder(128);
1231 tag.append("Low on memory -- ");
1232 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1233 tag, stack);
1234 dropBuilder.append(stack);
1235 dropBuilder.append('\n');
1236 dropBuilder.append('\n');
1237 String oomString = oomSw.toString();
1238 dropBuilder.append(oomString);
1239 dropBuilder.append('\n');
1240 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001241 try {
1242 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1243 "procrank", });
1244 final InputStreamReader converter = new InputStreamReader(
1245 proc.getInputStream());
1246 BufferedReader in = new BufferedReader(converter);
1247 String line;
1248 while (true) {
1249 line = in.readLine();
1250 if (line == null) {
1251 break;
1252 }
1253 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001254 logBuilder.append(line);
1255 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001256 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001257 dropBuilder.append(line);
1258 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001259 }
1260 converter.close();
1261 } catch (IOException e) {
1262 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001263 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001264 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001265 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001266 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001267 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001268 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001269 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001270 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001271 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001272 addErrorToDropBox("lowmem", null, "system_server", null,
1273 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001274 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001275 synchronized (ActivityManagerService.this) {
1276 long now = SystemClock.uptimeMillis();
1277 if (mLastMemUsageReportTime < now) {
1278 mLastMemUsageReportTime = now;
1279 }
1280 }
1281 }
1282 };
1283 thread.start();
1284 break;
1285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 }
1287 }
1288 };
1289
1290 public static void setSystemProcess() {
1291 try {
1292 ActivityManagerService m = mSelf;
1293
1294 ServiceManager.addService("activity", m);
1295 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001296 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 if (MONITOR_CPU_USAGE) {
1298 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 ServiceManager.addService("permission", new PermissionController(m));
1301
1302 ApplicationInfo info =
1303 mSelf.mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -07001304 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001305 mSystemThread.installSystemApplicationInfo(info);
1306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 synchronized (mSelf) {
1308 ProcessRecord app = mSelf.newProcessRecordLocked(
1309 mSystemThread.getApplicationThread(), info,
1310 info.processName);
1311 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001312 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001313 app.maxAdj = ProcessList.SYSTEM_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 mSelf.mProcessNames.put(app.processName, app.info.uid, app);
1315 synchronized (mSelf.mPidsSelfLocked) {
1316 mSelf.mPidsSelfLocked.put(app.pid, app);
1317 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001318 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 }
1320 } catch (PackageManager.NameNotFoundException e) {
1321 throw new RuntimeException(
1322 "Unable to find android system package", e);
1323 }
1324 }
1325
1326 public void setWindowManager(WindowManagerService wm) {
1327 mWindowManager = wm;
1328 }
1329
1330 public static final Context main(int factoryTest) {
1331 AThread thr = new AThread();
1332 thr.start();
1333
1334 synchronized (thr) {
1335 while (thr.mService == null) {
1336 try {
1337 thr.wait();
1338 } catch (InterruptedException e) {
1339 }
1340 }
1341 }
1342
1343 ActivityManagerService m = thr.mService;
1344 mSelf = m;
1345 ActivityThread at = ActivityThread.systemMain();
1346 mSystemThread = at;
1347 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001348 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 m.mContext = context;
1350 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001351 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352
1353 m.mBatteryStatsService.publish(context);
1354 m.mUsageStatsService.publish(context);
1355
1356 synchronized (thr) {
1357 thr.mReady = true;
1358 thr.notifyAll();
1359 }
1360
1361 m.startRunning(null, null, null, null);
1362
1363 return context;
1364 }
1365
1366 public static ActivityManagerService self() {
1367 return mSelf;
1368 }
1369
1370 static class AThread extends Thread {
1371 ActivityManagerService mService;
1372 boolean mReady = false;
1373
1374 public AThread() {
1375 super("ActivityManager");
1376 }
1377
1378 public void run() {
1379 Looper.prepare();
1380
1381 android.os.Process.setThreadPriority(
1382 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001383 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384
1385 ActivityManagerService m = new ActivityManagerService();
1386
1387 synchronized (this) {
1388 mService = m;
1389 notifyAll();
1390 }
1391
1392 synchronized (this) {
1393 while (!mReady) {
1394 try {
1395 wait();
1396 } catch (InterruptedException e) {
1397 }
1398 }
1399 }
1400
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001401 // For debug builds, log event loop stalls to dropbox for analysis.
1402 if (StrictMode.conditionallyEnableDebugLogging()) {
1403 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1404 }
1405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 Looper.loop();
1407 }
1408 }
1409
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001410 static class MemBinder extends Binder {
1411 ActivityManagerService mActivityManagerService;
1412 MemBinder(ActivityManagerService activityManagerService) {
1413 mActivityManagerService = activityManagerService;
1414 }
1415
1416 @Override
1417 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001418 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1419 != PackageManager.PERMISSION_GRANTED) {
1420 pw.println("Permission Denial: can't dump meminfo from from pid="
1421 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1422 + " without permission " + android.Manifest.permission.DUMP);
1423 return;
1424 }
1425
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001426 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001427 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 }
1429 }
1430
Chet Haase9c1e23b2011-03-24 10:51:31 -07001431 static class GraphicsBinder extends Binder {
1432 ActivityManagerService mActivityManagerService;
1433 GraphicsBinder(ActivityManagerService activityManagerService) {
1434 mActivityManagerService = activityManagerService;
1435 }
1436
1437 @Override
1438 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001439 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1440 != PackageManager.PERMISSION_GRANTED) {
1441 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1442 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1443 + " without permission " + android.Manifest.permission.DUMP);
1444 return;
1445 }
1446
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001447 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001448 }
1449 }
1450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 static class CpuBinder extends Binder {
1452 ActivityManagerService mActivityManagerService;
1453 CpuBinder(ActivityManagerService activityManagerService) {
1454 mActivityManagerService = activityManagerService;
1455 }
1456
1457 @Override
1458 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001459 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1460 != PackageManager.PERMISSION_GRANTED) {
1461 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1462 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1463 + " without permission " + android.Manifest.permission.DUMP);
1464 return;
1465 }
1466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001467 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001468 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1469 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1470 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 }
1472 }
1473 }
1474
1475 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001476 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 File dataDir = Environment.getDataDirectory();
1479 File systemDir = new File(dataDir, "system");
1480 systemDir.mkdirs();
1481 mBatteryStatsService = new BatteryStatsService(new File(
1482 systemDir, "batterystats.bin").toString());
1483 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001484 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001485 mOnBattery = DEBUG_POWER ? true
1486 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001487 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001489 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001490 systemDir, "usagestats").toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491
Jack Palevichb90d28c2009-07-22 15:35:24 -07001492 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1493 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1494
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001495 mConfiguration.setToDefaults();
1496 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001497 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 mProcessStats.init();
1499
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001500 mCompatModePackages = new CompatModePackages(this, systemDir);
1501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 // Add ourself to the Watchdog monitors.
1503 Watchdog.getInstance().addMonitor(this);
1504
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 mProcessStatsThread = new Thread("ProcessStats") {
1506 public void run() {
1507 while (true) {
1508 try {
1509 try {
1510 synchronized(this) {
1511 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001512 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001514 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 // + ", write delay=" + nextWriteDelay);
1516 if (nextWriteDelay < nextCpuDelay) {
1517 nextCpuDelay = nextWriteDelay;
1518 }
1519 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001520 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001521 this.wait(nextCpuDelay);
1522 }
1523 }
1524 } catch (InterruptedException e) {
1525 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526 updateCpuStatsNow();
1527 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001528 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 }
1530 }
1531 }
1532 };
1533 mProcessStatsThread.start();
1534 }
1535
1536 @Override
1537 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1538 throws RemoteException {
1539 try {
1540 return super.onTransact(code, data, reply, flags);
1541 } catch (RuntimeException e) {
1542 // The activity manager only throws security exceptions, so let's
1543 // log all others.
1544 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001545 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001546 }
1547 throw e;
1548 }
1549 }
1550
1551 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001552 final long now = SystemClock.uptimeMillis();
1553 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1554 return;
1555 }
1556 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1557 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 mProcessStatsThread.notify();
1559 }
1560 }
1561 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001562
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 void updateCpuStatsNow() {
1564 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001565 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 final long now = SystemClock.uptimeMillis();
1567 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001568
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001570 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1571 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 haveNewCpuStats = true;
1573 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001574 //Slog.i(TAG, mProcessStats.printCurrentState());
1575 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 // + mProcessStats.getTotalCpuPercent() + "%");
1577
Joe Onorato8a9b2202010-02-26 18:56:32 -08001578 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 if ("true".equals(SystemProperties.get("events.cpu"))) {
1580 int user = mProcessStats.getLastUserTime();
1581 int system = mProcessStats.getLastSystemTime();
1582 int iowait = mProcessStats.getLastIoWaitTime();
1583 int irq = mProcessStats.getLastIrqTime();
1584 int softIrq = mProcessStats.getLastSoftIrqTime();
1585 int idle = mProcessStats.getLastIdleTime();
1586
1587 int total = user + system + iowait + irq + softIrq + idle;
1588 if (total == 0) total = 1;
1589
Doug Zongker2bec3d42009-12-04 12:52:44 -08001590 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 ((user+system+iowait+irq+softIrq) * 100) / total,
1592 (user * 100) / total,
1593 (system * 100) / total,
1594 (iowait * 100) / total,
1595 (irq * 100) / total,
1596 (softIrq * 100) / total);
1597 }
1598 }
1599
Amith Yamasanie43530a2009-08-21 13:11:37 -07001600 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001601 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001602 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 synchronized(mPidsSelfLocked) {
1604 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001605 if (mOnBattery) {
1606 int perc = bstats.startAddingCpuLocked();
1607 int totalUTime = 0;
1608 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001609 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001610 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001611 ProcessStats.Stats st = mProcessStats.getStats(i);
1612 if (!st.working) {
1613 continue;
1614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001616 int otherUTime = (st.rel_utime*perc)/100;
1617 int otherSTime = (st.rel_stime*perc)/100;
1618 totalUTime += otherUTime;
1619 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 if (pr != null) {
1621 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001622 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1623 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001624 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001625 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001626 } else {
1627 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001628 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001629 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001630 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1631 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001632 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001633 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 }
1635 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001636 bstats.finishAddingCpuLocked(perc, totalUTime,
1637 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638 }
1639 }
1640 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1643 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001644 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645 }
1646 }
1647 }
1648 }
1649
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001650 @Override
1651 public void batteryNeedsCpuUpdate() {
1652 updateCpuStatsNow();
1653 }
1654
1655 @Override
1656 public void batteryPowerChanged(boolean onBattery) {
1657 // When plugging in, update the CPU stats first before changing
1658 // the plug state.
1659 updateCpuStatsNow();
1660 synchronized (this) {
1661 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001662 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001663 }
1664 }
1665 }
1666
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667 /**
1668 * Initialize the application bind args. These are passed to each
1669 * process when the bindApplication() IPC is sent to the process. They're
1670 * lazily setup to make sure the services are running when they're asked for.
1671 */
1672 private HashMap<String, IBinder> getCommonServicesLocked() {
1673 if (mAppBindArgs == null) {
1674 mAppBindArgs = new HashMap<String, IBinder>();
1675
1676 // Setup the application init args
1677 mAppBindArgs.put("package", ServiceManager.getService("package"));
1678 mAppBindArgs.put("window", ServiceManager.getService("window"));
1679 mAppBindArgs.put(Context.ALARM_SERVICE,
1680 ServiceManager.getService(Context.ALARM_SERVICE));
1681 }
1682 return mAppBindArgs;
1683 }
1684
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001685 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 if (mFocusedActivity != r) {
1687 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001688 if (r != null) {
1689 mWindowManager.setFocusedApp(r.appToken, true);
1690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 }
1692 }
1693
Dianne Hackborn906497c2010-05-10 15:57:38 -07001694 private final void updateLruProcessInternalLocked(ProcessRecord app,
1695 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001696 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001697 int lrui = mLruProcesses.indexOf(app);
1698 if (lrui >= 0) mLruProcesses.remove(lrui);
1699
1700 int i = mLruProcesses.size()-1;
1701 int skipTop = 0;
1702
Dianne Hackborn906497c2010-05-10 15:57:38 -07001703 app.lruSeq = mLruSeq;
1704
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001705 // compute the new weight for this process.
1706 if (updateActivityTime) {
1707 app.lastActivityTime = SystemClock.uptimeMillis();
1708 }
1709 if (app.activities.size() > 0) {
1710 // If this process has activities, we more strongly want to keep
1711 // it around.
1712 app.lruWeight = app.lastActivityTime;
1713 } else if (app.pubProviders.size() > 0) {
1714 // If this process contains content providers, we want to keep
1715 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001716 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001717 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001718 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001719 } else {
1720 // If this process doesn't have activities, we less strongly
1721 // want to keep it around, and generally want to avoid getting
1722 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001723 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001724 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001725 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001726 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001727
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001728 while (i >= 0) {
1729 ProcessRecord p = mLruProcesses.get(i);
1730 // If this app shouldn't be in front of the first N background
1731 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001732 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001733 skipTop--;
1734 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001735 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001736 mLruProcesses.add(i+1, app);
1737 break;
1738 }
1739 i--;
1740 }
1741 if (i < 0) {
1742 mLruProcesses.add(0, app);
1743 }
1744
Dianne Hackborn906497c2010-05-10 15:57:38 -07001745 // If the app is currently using a content provider or service,
1746 // bump those processes as well.
1747 if (app.connections.size() > 0) {
1748 for (ConnectionRecord cr : app.connections) {
1749 if (cr.binding != null && cr.binding.service != null
1750 && cr.binding.service.app != null
1751 && cr.binding.service.app.lruSeq != mLruSeq) {
1752 updateLruProcessInternalLocked(cr.binding.service.app, oomAdj,
1753 updateActivityTime, i+1);
1754 }
1755 }
1756 }
1757 if (app.conProviders.size() > 0) {
1758 for (ContentProviderRecord cpr : app.conProviders.keySet()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07001759 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
1760 updateLruProcessInternalLocked(cpr.proc, oomAdj,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001761 updateActivityTime, i+1);
1762 }
1763 }
1764 }
1765
Joe Onorato8a9b2202010-02-26 18:56:32 -08001766 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 if (oomAdj) {
1768 updateOomAdjLocked();
1769 }
1770 }
1771
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001772 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001773 boolean oomAdj, boolean updateActivityTime) {
1774 mLruSeq++;
1775 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1776 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001777
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001778 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001779 String processName, int uid) {
1780 if (uid == Process.SYSTEM_UID) {
1781 // The system gets to run in any process. If there are multiple
1782 // processes with the same uid, just pick the first (this
1783 // should never happen).
1784 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1785 processName);
1786 return procs != null ? procs.valueAt(0) : null;
1787 }
1788 ProcessRecord proc = mProcessNames.get(processName, uid);
1789 return proc;
1790 }
1791
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001792 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001793 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001794 try {
1795 if (pm.performDexOpt(packageName)) {
1796 mDidDexOpt = true;
1797 }
1798 } catch (RemoteException e) {
1799 }
1800 }
1801
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001802 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 int transit = mWindowManager.getPendingAppTransition();
1804 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1805 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1806 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1807 }
1808
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001809 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001810 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001811 String hostingType, ComponentName hostingName, boolean allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 ProcessRecord app = getProcessRecordLocked(processName, info.uid);
1813 // We don't have to do anything more if:
1814 // (1) There is an existing application record; and
1815 // (2) The caller doesn't think it is dead, OR there is no thread
1816 // object attached to it so we know it couldn't have crashed; and
1817 // (3) There is a pid assigned to it, so it is either starting or
1818 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001819 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001820 + " app=" + app + " knownToBeDead=" + knownToBeDead
1821 + " thread=" + (app != null ? app.thread : null)
1822 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001823 if (app != null && app.pid > 0) {
1824 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001825 // We already have the app running, or are waiting for it to
1826 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001827 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001828 // If this is a new package in the process, add the package to the list
1829 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001830 return app;
1831 } else {
1832 // An application record is attached to a previous process,
1833 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001834 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001835 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001837 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 String hostingNameStr = hostingName != null
1840 ? hostingName.flattenToShortString() : null;
1841
1842 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1843 // If we are in the background, then check to see if this process
1844 // is bad. If so, we will just silently fail.
1845 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001846 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1847 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001848 return null;
1849 }
1850 } else {
1851 // When the user is explicitly starting a process, then clear its
1852 // crash count so that we won't make it bad until they see at
1853 // least one crash dialog again, and make the process good again
1854 // if it had been bad.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001855 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
1856 + "/" + info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 mProcessCrashTimes.remove(info.processName, info.uid);
1858 if (mBadProcesses.get(info.processName, info.uid) != null) {
Doug Zongker2bec3d42009-12-04 12:52:44 -08001859 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001860 info.processName);
1861 mBadProcesses.remove(info.processName, info.uid);
1862 if (app != null) {
1863 app.bad = false;
1864 }
1865 }
1866 }
1867
1868 if (app == null) {
1869 app = newProcessRecordLocked(null, info, processName);
1870 mProcessNames.put(processName, info.uid, app);
1871 } else {
1872 // If this is a new package in the process, add the package to the list
1873 app.addPackage(info.packageName);
1874 }
1875
1876 // If the system is not ready yet, then hold off on starting this
1877 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001878 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001879 && !isAllowedWhileBooting(info)
1880 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001881 if (!mProcessesOnHold.contains(app)) {
1882 mProcessesOnHold.add(app);
1883 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001884 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885 return app;
1886 }
1887
1888 startProcessLocked(app, hostingType, hostingNameStr);
1889 return (app.pid != 0) ? app : null;
1890 }
1891
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001892 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1893 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1894 }
1895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 private final void startProcessLocked(ProcessRecord app,
1897 String hostingType, String hostingNameStr) {
1898 if (app.pid > 0 && app.pid != MY_PID) {
1899 synchronized (mPidsSelfLocked) {
1900 mPidsSelfLocked.remove(app.pid);
1901 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1902 }
1903 app.pid = 0;
1904 }
1905
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001906 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1907 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 mProcessesOnHold.remove(app);
1909
1910 updateCpuStats();
1911
1912 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1913 mProcDeaths[0] = 0;
1914
1915 try {
1916 int uid = app.info.uid;
1917 int[] gids = null;
1918 try {
1919 gids = mContext.getPackageManager().getPackageGids(
1920 app.info.packageName);
1921 } catch (PackageManager.NameNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001922 Slog.w(TAG, "Unable to retrieve gids", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 }
1924 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
1925 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
1926 && mTopComponent != null
1927 && app.processName.equals(mTopComponent.getPackageName())) {
1928 uid = 0;
1929 }
1930 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
1931 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
1932 uid = 0;
1933 }
1934 }
1935 int debugFlags = 0;
1936 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
1937 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07001938 // Also turn on CheckJNI for debuggable apps. It's quite
1939 // awkward to turn on otherwise.
1940 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001941 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08001942 // Run the app in safe mode if its manifest requests so or the
1943 // system is booted in safe mode.
1944 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
1945 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08001946 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
1947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
1949 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
1950 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07001951 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
1952 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
1953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 if ("1".equals(SystemProperties.get("debug.assert"))) {
1955 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
1956 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07001957
1958 // Start the process. It will either succeed and return a result containing
1959 // the PID of the new process, or else throw a RuntimeException.
1960 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07001961 app.processName, uid, uid, gids, debugFlags,
1962 app.info.targetSdkVersion, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07001963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
1965 synchronized (bs) {
1966 if (bs.isOnBattery()) {
1967 app.batteryStats.incStartsLocked();
1968 }
1969 }
1970
Jeff Brown3f9dd282011-07-08 20:02:19 -07001971 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 app.processName, hostingType,
1973 hostingNameStr != null ? hostingNameStr : "");
1974
1975 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07001976 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 }
1978
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07001979 StringBuilder buf = mStringBuilder;
1980 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 buf.append("Start proc ");
1982 buf.append(app.processName);
1983 buf.append(" for ");
1984 buf.append(hostingType);
1985 if (hostingNameStr != null) {
1986 buf.append(" ");
1987 buf.append(hostingNameStr);
1988 }
1989 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07001990 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001991 buf.append(" uid=");
1992 buf.append(uid);
1993 buf.append(" gids={");
1994 if (gids != null) {
1995 for (int gi=0; gi<gids.length; gi++) {
1996 if (gi != 0) buf.append(", ");
1997 buf.append(gids[gi]);
1998
1999 }
2000 }
2001 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002002 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002003 app.pid = startResult.pid;
2004 app.usingWrapper = startResult.usingWrapper;
2005 app.removed = false;
2006 synchronized (mPidsSelfLocked) {
2007 this.mPidsSelfLocked.put(startResult.pid, app);
2008 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2009 msg.obj = app;
2010 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2011 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002012 }
2013 } catch (RuntimeException e) {
2014 // XXX do better error recovery.
2015 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002016 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 }
2018 }
2019
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002020 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002021 if (resumed) {
2022 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2023 } else {
2024 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2025 }
2026 }
2027
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002028 boolean startHomeActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002029 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2030 && mTopAction == null) {
2031 // We are running in factory test mode, but unable to find
2032 // the factory test app, so just sit around displaying the
2033 // error message and don't try to start anything.
2034 return false;
2035 }
2036 Intent intent = new Intent(
2037 mTopAction,
2038 mTopData != null ? Uri.parse(mTopData) : null);
2039 intent.setComponent(mTopComponent);
2040 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2041 intent.addCategory(Intent.CATEGORY_HOME);
2042 }
2043 ActivityInfo aInfo =
2044 intent.resolveActivityInfo(mContext.getPackageManager(),
2045 STOCK_PM_FLAGS);
2046 if (aInfo != null) {
2047 intent.setComponent(new ComponentName(
2048 aInfo.applicationInfo.packageName, aInfo.name));
2049 // Don't do this if the home app is currently being
2050 // instrumented.
2051 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2052 aInfo.applicationInfo.uid);
2053 if (app == null || app.instrumentationClass == null) {
2054 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002055 mMainStack.startActivityLocked(null, intent, null, null, 0, aInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002056 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002057 }
2058 }
2059
2060
2061 return true;
2062 }
2063
2064 /**
2065 * Starts the "new version setup screen" if appropriate.
2066 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002067 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002068 // Only do this once per boot.
2069 if (mCheckedForSetup) {
2070 return;
2071 }
2072
2073 // We will show this screen if the current one is a different
2074 // version than the last one shown, and we are not running in
2075 // low-level factory test mode.
2076 final ContentResolver resolver = mContext.getContentResolver();
2077 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2078 Settings.Secure.getInt(resolver,
2079 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2080 mCheckedForSetup = true;
2081
2082 // See if we should be showing the platform update setup UI.
2083 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2084 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2085 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2086
2087 // We don't allow third party apps to replace this.
2088 ResolveInfo ri = null;
2089 for (int i=0; ris != null && i<ris.size(); i++) {
2090 if ((ris.get(i).activityInfo.applicationInfo.flags
2091 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2092 ri = ris.get(i);
2093 break;
2094 }
2095 }
2096
2097 if (ri != null) {
2098 String vers = ri.activityInfo.metaData != null
2099 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2100 : null;
2101 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2102 vers = ri.activityInfo.applicationInfo.metaData.getString(
2103 Intent.METADATA_SETUP_VERSION);
2104 }
2105 String lastVers = Settings.Secure.getString(
2106 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2107 if (vers != null && !vers.equals(lastVers)) {
2108 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2109 intent.setComponent(new ComponentName(
2110 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002111 mMainStack.startActivityLocked(null, intent, null, null, 0, ri.activityInfo,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002112 null, null, 0, 0, 0, false, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002113 }
2114 }
2115 }
2116 }
2117
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002118 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002119 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002120 }
2121
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002122 public int getFrontActivityScreenCompatMode() {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002123 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002124 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2125 }
2126 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002127
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002128 public void setFrontActivityScreenCompatMode(int mode) {
2129 synchronized (this) {
2130 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2131 }
2132 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002133
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002134 public int getPackageScreenCompatMode(String packageName) {
2135 synchronized (this) {
2136 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2137 }
2138 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002139
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002140 public void setPackageScreenCompatMode(String packageName, int mode) {
2141 synchronized (this) {
2142 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002143 }
2144 }
2145
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002146 public boolean getPackageAskScreenCompat(String packageName) {
2147 synchronized (this) {
2148 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2149 }
2150 }
2151
2152 public void setPackageAskScreenCompat(String packageName, boolean ask) {
2153 synchronized (this) {
2154 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2155 }
2156 }
2157
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002158 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002159 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002160
2161 final int identHash = System.identityHashCode(r);
2162 updateUsageStats(r, true);
2163
2164 int i = mWatchers.beginBroadcast();
2165 while (i > 0) {
2166 i--;
2167 IActivityWatcher w = mWatchers.getBroadcastItem(i);
2168 if (w != null) {
2169 try {
2170 w.activityResuming(identHash);
2171 } catch (RemoteException e) {
2172 }
2173 }
2174 }
2175 mWatchers.finishBroadcast();
2176 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002177
Jeff Sharkeya4620792011-05-20 15:29:23 -07002178 private void dispatchForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
2179 int i = mProcessObservers.beginBroadcast();
2180 while (i > 0) {
2181 i--;
2182 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2183 if (observer != null) {
2184 try {
2185 observer.onForegroundActivitiesChanged(pid, uid, foregroundActivities);
2186 } catch (RemoteException e) {
2187 }
2188 }
2189 }
2190 mProcessObservers.finishBroadcast();
2191 }
2192
2193 private void dispatchProcessDied(int pid, int uid) {
2194 int i = mProcessObservers.beginBroadcast();
2195 while (i > 0) {
2196 i--;
2197 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2198 if (observer != null) {
2199 try {
2200 observer.onProcessDied(pid, uid);
2201 } catch (RemoteException e) {
2202 }
2203 }
2204 }
2205 mProcessObservers.finishBroadcast();
2206 }
2207
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002208 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002209 final int N = mPendingActivityLaunches.size();
2210 if (N <= 0) {
2211 return;
2212 }
2213 for (int i=0; i<N; i++) {
2214 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002215 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002216 pal.grantedUriPermissions, pal.grantedMode, pal.onlyIfNeeded,
2217 doResume && i == (N-1));
2218 }
2219 mPendingActivityLaunches.clear();
2220 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002221
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002222 public final int startActivity(IApplicationThread caller,
2223 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2224 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002225 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2226 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002227 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002228 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002229 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2230 null, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002231 }
2232
2233 public final WaitResult startActivityAndWait(IApplicationThread caller,
2234 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2235 int grantedMode, IBinder resultTo,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002236 String resultWho, int requestCode, boolean onlyIfNeeded, boolean debug,
2237 String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002238 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002239 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002240 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002241 requestCode, onlyIfNeeded, debug, profileFile, profileFd, autoStopProfiler,
2242 res, null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002243 return res;
2244 }
2245
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002246 public final int startActivityWithConfig(IApplicationThread caller,
2247 Intent intent, String resolvedType, Uri[] grantedUriPermissions,
2248 int grantedMode, IBinder resultTo,
2249 String resultWho, int requestCode, boolean onlyIfNeeded,
2250 boolean debug, Configuration config) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002251 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002252 grantedUriPermissions, grantedMode, resultTo, resultWho,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002253 requestCode, onlyIfNeeded, debug, null, null, false, null, config);
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002254 }
2255
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002256 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002257 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002258 IBinder resultTo, String resultWho, int requestCode,
2259 int flagsMask, int flagsValues) {
2260 // Refuse possible leaked file descriptors
2261 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2262 throw new IllegalArgumentException("File descriptors passed in Intent");
2263 }
2264
2265 IIntentSender sender = intent.getTarget();
2266 if (!(sender instanceof PendingIntentRecord)) {
2267 throw new IllegalArgumentException("Bad PendingIntent object");
2268 }
2269
2270 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002271
2272 synchronized (this) {
2273 // If this is coming from the currently resumed activity, it is
2274 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002275 if (mMainStack.mResumedActivity != null
2276 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002277 Binder.getCallingUid()) {
2278 mAppSwitchesAllowedTime = 0;
2279 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002280 }
2281
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002282 return pir.sendInner(0, fillInIntent, resolvedType, null,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002283 null, resultTo, resultWho, requestCode, flagsMask, flagsValues);
2284 }
2285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 public boolean startNextMatchingActivity(IBinder callingActivity,
2287 Intent intent) {
2288 // Refuse possible leaked file descriptors
2289 if (intent != null && intent.hasFileDescriptors() == true) {
2290 throw new IllegalArgumentException("File descriptors passed in Intent");
2291 }
2292
2293 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002294 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2295 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 return false;
2297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002298 if (r.app == null || r.app.thread == null) {
2299 // The caller is not running... d'oh!
2300 return false;
2301 }
2302 intent = new Intent(intent);
2303 // The caller is not allowed to change the data.
2304 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2305 // And we are resetting to find the next component...
2306 intent.setComponent(null);
2307
2308 ActivityInfo aInfo = null;
2309 try {
2310 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002311 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002312 intent, r.resolvedType,
Dianne Hackborn1655be42009-05-08 14:29:01 -07002313 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314
2315 // Look for the original activity in the list...
2316 final int N = resolves != null ? resolves.size() : 0;
2317 for (int i=0; i<N; i++) {
2318 ResolveInfo rInfo = resolves.get(i);
2319 if (rInfo.activityInfo.packageName.equals(r.packageName)
2320 && rInfo.activityInfo.name.equals(r.info.name)) {
2321 // We found the current one... the next matching is
2322 // after it.
2323 i++;
2324 if (i<N) {
2325 aInfo = resolves.get(i).activityInfo;
2326 }
2327 break;
2328 }
2329 }
2330 } catch (RemoteException e) {
2331 }
2332
2333 if (aInfo == null) {
2334 // Nobody who is next!
2335 return false;
2336 }
2337
2338 intent.setComponent(new ComponentName(
2339 aInfo.applicationInfo.packageName, aInfo.name));
2340 intent.setFlags(intent.getFlags()&~(
2341 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2342 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2343 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2344 Intent.FLAG_ACTIVITY_NEW_TASK));
2345
2346 // Okay now we need to start the new activity, replacing the
2347 // currently running activity. This is a little tricky because
2348 // we want to start the new one as if the current one is finished,
2349 // but not finish the current one first so that there is no flicker.
2350 // And thus...
2351 final boolean wasFinishing = r.finishing;
2352 r.finishing = true;
2353
2354 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002355 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002356 final String resultWho = r.resultWho;
2357 final int requestCode = r.requestCode;
2358 r.resultTo = null;
2359 if (resultTo != null) {
2360 resultTo.removeResultsLocked(r, resultWho, requestCode);
2361 }
2362
2363 final long origId = Binder.clearCallingIdentity();
2364 // XXX we are not dealing with propagating grantedUriPermissions...
2365 // those are not yet exposed to user code, so there is no need.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002366 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002367 r.resolvedType, null, 0, aInfo,
2368 resultTo != null ? resultTo.appToken : null, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002369 requestCode, -1, r.launchedFromUid, false, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 Binder.restoreCallingIdentity(origId);
2371
2372 r.finishing = wasFinishing;
2373 if (res != START_SUCCESS) {
2374 return false;
2375 }
2376 return true;
2377 }
2378 }
2379
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002380 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 Intent intent, String resolvedType, IBinder resultTo,
2382 String resultWho, int requestCode, boolean onlyIfNeeded) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002383
2384 // This is so super not safe, that only the system (or okay root)
2385 // can do it.
2386 final int callingUid = Binder.getCallingUid();
2387 if (callingUid != 0 && callingUid != Process.myUid()) {
2388 throw new SecurityException(
2389 "startActivityInPackage only available to the system");
2390 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002391
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002392 return mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002393 null, 0, resultTo, resultWho, requestCode, onlyIfNeeded, false,
2394 null, null, false, null, null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002395 }
2396
2397 public final int startActivities(IApplicationThread caller,
2398 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2399 return mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo);
2400 }
2401
2402 public final int startActivitiesInPackage(int uid,
2403 Intent[] intents, String[] resolvedTypes, IBinder resultTo) {
2404
2405 // This is so super not safe, that only the system (or okay root)
2406 // can do it.
2407 final int callingUid = Binder.getCallingUid();
2408 if (callingUid != 0 && callingUid != Process.myUid()) {
2409 throw new SecurityException(
2410 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002411 }
2412
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002413 return mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 }
2415
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002416 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002417 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002418 // Quick case: check if the top-most recent task is the same.
2419 if (N > 0 && mRecentTasks.get(0) == task) {
2420 return;
2421 }
2422 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 for (int i=0; i<N; i++) {
2424 TaskRecord tr = mRecentTasks.get(i);
2425 if ((task.affinity != null && task.affinity.equals(tr.affinity))
2426 || (task.intent != null && task.intent.filterEquals(tr.intent))) {
2427 mRecentTasks.remove(i);
2428 i--;
2429 N--;
2430 if (task.intent == null) {
2431 // If the new recent task we are adding is not fully
2432 // specified, then replace it with the existing recent task.
2433 task = tr;
2434 }
2435 }
2436 }
2437 if (N >= MAX_RECENT_TASKS) {
2438 mRecentTasks.remove(N-1);
2439 }
2440 mRecentTasks.add(0, task);
2441 }
2442
2443 public void setRequestedOrientation(IBinder token,
2444 int requestedOrientation) {
2445 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002446 ActivityRecord r = mMainStack.isInStackLocked(token);
2447 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 return;
2449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002450 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002451 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002453 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002454 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002455 if (config != null) {
2456 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002457 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002458 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002459 }
2460 }
2461 Binder.restoreCallingIdentity(origId);
2462 }
2463 }
2464
2465 public int getRequestedOrientation(IBinder token) {
2466 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002467 ActivityRecord r = mMainStack.isInStackLocked(token);
2468 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002469 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2470 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002471 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472 }
2473 }
2474
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002475 /**
2476 * This is the internal entry point for handling Activity.finish().
2477 *
2478 * @param token The Binder token referencing the Activity we want to finish.
2479 * @param resultCode Result code, if any, from this Activity.
2480 * @param resultData Result data (Intent), if any, from this Activity.
2481 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002482 * @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 -08002483 */
2484 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2485 // Refuse possible leaked file descriptors
2486 if (resultData != null && resultData.hasFileDescriptors() == true) {
2487 throw new IllegalArgumentException("File descriptors passed in Intent");
2488 }
2489
2490 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002491 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002492 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002493 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002494 if (next != null) {
2495 // ask watcher if this is allowed
2496 boolean resumeOK = true;
2497 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002498 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002499 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002500 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002501 }
2502
2503 if (!resumeOK) {
2504 return false;
2505 }
2506 }
2507 }
2508 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002509 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002510 resultData, "app-request");
2511 Binder.restoreCallingIdentity(origId);
2512 return res;
2513 }
2514 }
2515
Dianne Hackborn860755f2010-06-03 18:47:52 -07002516 public final void finishHeavyWeightApp() {
2517 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2518 != PackageManager.PERMISSION_GRANTED) {
2519 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2520 + Binder.getCallingPid()
2521 + ", uid=" + Binder.getCallingUid()
2522 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2523 Slog.w(TAG, msg);
2524 throw new SecurityException(msg);
2525 }
2526
2527 synchronized(this) {
2528 if (mHeavyWeightProcess == null) {
2529 return;
2530 }
2531
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002532 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002533 mHeavyWeightProcess.activities);
2534 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002535 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002536 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002537 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002538 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002539 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002540 null, "finish-heavy");
2541 }
2542 }
2543 }
2544
2545 mHeavyWeightProcess = null;
2546 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2547 }
2548 }
2549
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002550 public void crashApplication(int uid, int initialPid, String packageName,
2551 String message) {
2552 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2553 != PackageManager.PERMISSION_GRANTED) {
2554 String msg = "Permission Denial: crashApplication() from pid="
2555 + Binder.getCallingPid()
2556 + ", uid=" + Binder.getCallingUid()
2557 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2558 Slog.w(TAG, msg);
2559 throw new SecurityException(msg);
2560 }
2561
2562 synchronized(this) {
2563 ProcessRecord proc = null;
2564
2565 // Figure out which process to kill. We don't trust that initialPid
2566 // still has any relation to current pids, so must scan through the
2567 // list.
2568 synchronized (mPidsSelfLocked) {
2569 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2570 ProcessRecord p = mPidsSelfLocked.valueAt(i);
2571 if (p.info.uid != uid) {
2572 continue;
2573 }
2574 if (p.pid == initialPid) {
2575 proc = p;
2576 break;
2577 }
2578 for (String str : p.pkgList) {
2579 if (str.equals(packageName)) {
2580 proc = p;
2581 }
2582 }
2583 }
2584 }
2585
2586 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002587 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002588 + " initialPid=" + initialPid
2589 + " packageName=" + packageName);
2590 return;
2591 }
2592
2593 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002594 if (proc.pid == Process.myPid()) {
2595 Log.w(TAG, "crashApplication: trying to crash self!");
2596 return;
2597 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002598 long ident = Binder.clearCallingIdentity();
2599 try {
2600 proc.thread.scheduleCrash(message);
2601 } catch (RemoteException e) {
2602 }
2603 Binder.restoreCallingIdentity(ident);
2604 }
2605 }
2606 }
2607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 public final void finishSubActivity(IBinder token, String resultWho,
2609 int requestCode) {
2610 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002611 ActivityRecord self = mMainStack.isInStackLocked(token);
2612 if (self == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002613 return;
2614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615
2616 final long origId = Binder.clearCallingIdentity();
2617
2618 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002619 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2620 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 if (r.resultTo == self && r.requestCode == requestCode) {
2622 if ((r.resultWho == null && resultWho == null) ||
2623 (r.resultWho != null && r.resultWho.equals(resultWho))) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002624 mMainStack.finishActivityLocked(r, i,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 Activity.RESULT_CANCELED, null, "request-sub");
2626 }
2627 }
2628 }
2629
2630 Binder.restoreCallingIdentity(origId);
2631 }
2632 }
2633
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002634 public boolean willActivityBeVisible(IBinder token) {
2635 synchronized(this) {
2636 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002637 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2638 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002639 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002640 return true;
2641 }
2642 if (r.fullscreen && !r.finishing) {
2643 return false;
2644 }
2645 }
2646 return true;
2647 }
2648 }
2649
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002650 public void overridePendingTransition(IBinder token, String packageName,
2651 int enterAnim, int exitAnim) {
2652 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002653 ActivityRecord self = mMainStack.isInStackLocked(token);
2654 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002655 return;
2656 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002657
2658 final long origId = Binder.clearCallingIdentity();
2659
2660 if (self.state == ActivityState.RESUMED
2661 || self.state == ActivityState.PAUSING) {
2662 mWindowManager.overridePendingAppTransition(packageName,
2663 enterAnim, exitAnim);
2664 }
2665
2666 Binder.restoreCallingIdentity(origId);
2667 }
2668 }
2669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002670 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 * Main function for removing an existing process from the activity manager
2672 * as a result of that process going away. Clears out all connections
2673 * to the process.
2674 */
2675 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002676 boolean restarting, boolean allowRestart) {
2677 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002678 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002679 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 }
2681
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002682 if (mProfileProc == app) {
2683 clearProfilerLocked();
2684 }
2685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 // Just in case...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002687 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2688 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2689 mMainStack.mPausingActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002691 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2692 mMainStack.mLastPausedActivity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002693 }
2694
2695 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002696 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697
2698 boolean atTop = true;
2699 boolean hasVisibleActivities = false;
2700
2701 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002702 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002703 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002704 TAG, "Removing app " + app + " from history with " + i + " entries");
2705 while (i > 0) {
2706 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002707 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002708 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2710 if (r.app == app) {
2711 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002712 if (ActivityStack.DEBUG_ADD_REMOVE) {
2713 RuntimeException here = new RuntimeException("here");
2714 here.fillInStackTrace();
2715 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2716 + ": haveState=" + r.haveState
2717 + " stateNotNeeded=" + r.stateNotNeeded
2718 + " finishing=" + r.finishing
2719 + " state=" + r.state, here);
2720 }
2721 if (!r.finishing) {
2722 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
2723 }
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08002724 r.makeFinishing();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002725 mMainStack.mHistory.remove(i);
Dianne Hackbornf26fd992011-04-08 18:14:09 -07002726 r.takeFromHistory();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002727 mWindowManager.removeAppToken(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002728 if (VALIDATE_TOKENS) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002729 mMainStack.validateAppTokensLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002730 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002731 r.removeUriPermissionsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002732
2733 } else {
2734 // We have the current state for this activity, so
2735 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002736 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 TAG, "Keeping entry, setting app to null");
2738 if (r.visible) {
2739 hasVisibleActivities = true;
2740 }
2741 r.app = null;
2742 r.nowVisible = false;
2743 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002744 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2745 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 r.icicle = null;
2747 }
2748 }
2749
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002750 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 }
2752 atTop = false;
2753 }
2754
2755 app.activities.clear();
2756
2757 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002758 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 + " running instrumentation " + app.instrumentationClass);
2760 Bundle info = new Bundle();
2761 info.putString("shortMsg", "Process crashed.");
2762 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2763 }
2764
2765 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002766 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 // If there was nothing to resume, and we are not already
2768 // restarting this process, but there is a visible activity that
2769 // is hosted by the process... then make sure all visible
2770 // activities are running, taking care of restarting this
2771 // process.
2772 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002773 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 }
2775 }
2776 }
2777 }
2778
2779 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2780 IBinder threadBinder = thread.asBinder();
2781
2782 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002783 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2784 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2786 return i;
2787 }
2788 }
2789 return -1;
2790 }
2791
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002792 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 IApplicationThread thread) {
2794 if (thread == null) {
2795 return null;
2796 }
2797
2798 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002799 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002800 }
2801
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002802 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803 IApplicationThread thread) {
2804
2805 mProcDeaths[0]++;
2806
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002807 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2808 synchronized (stats) {
2809 stats.noteProcessDiedLocked(app.info.uid, pid);
2810 }
2811
Magnus Edlund7bb25812010-02-24 15:45:06 +01002812 // Clean up already done if the process has been re-started.
2813 if (app.pid == pid && app.thread != null &&
2814 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002815 if (!app.killedBackground) {
2816 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2817 + ") has died.");
2818 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002819 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 TAG, "Dying app: " + app + ", pid: " + pid
2822 + ", thread: " + thread.asBinder());
2823 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002824 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825
2826 if (doLowMem) {
2827 // If there are no longer any background processes running,
2828 // and the app that died was not running instrumentation,
2829 // then tell everyone we are now low on memory.
2830 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002831 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2832 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002833 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002834 haveBg = true;
2835 break;
2836 }
2837 }
2838
2839 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002840 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002841 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002842 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2843 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002844 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002845 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2846 // The low memory report is overriding any current
2847 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002848 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002849 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002850 rec.lastRequestedGc = 0;
2851 } else {
2852 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002854 rec.reportLowMemory = true;
2855 rec.lastLowMemory = now;
2856 mProcessesToGc.remove(rec);
2857 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002858 }
2859 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07002860 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002861 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 }
2863 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002864 } else if (app.pid != pid) {
2865 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002866 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01002867 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08002868 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08002869 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002870 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002871 + thread.asBinder());
2872 }
2873 }
2874
Dan Egnor42471dd2010-01-07 17:25:22 -08002875 /**
2876 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07002877 * @param clearTraces causes the dump file to be erased prior to the new
2878 * traces being written, if true; when false, the new traces will be
2879 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002880 * @param firstPids of dalvik VM processes to dump stack traces for first
2881 * @param lastPids of dalvik VM processes to dump stack traces for last
Dan Egnor42471dd2010-01-07 17:25:22 -08002882 * @return file containing stack traces, or null if no dump file is configured
2883 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002884 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
2885 ProcessStats processStats, SparseArray<Boolean> lastPids) {
Dan Egnor42471dd2010-01-07 17:25:22 -08002886 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
2887 if (tracesPath == null || tracesPath.length() == 0) {
2888 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002890
2891 File tracesFile = new File(tracesPath);
2892 try {
2893 File tracesDir = tracesFile.getParentFile();
2894 if (!tracesDir.exists()) tracesFile.mkdirs();
2895 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
2896
Christopher Tate6ee412d2010-05-28 12:01:56 -07002897 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08002898 tracesFile.createNewFile();
2899 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
2900 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002901 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08002902 return null;
2903 }
2904
2905 // Use a FileObserver to detect when traces finish writing.
2906 // The order of traces is considered important to maintain for legibility.
2907 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
2908 public synchronized void onEvent(int event, String path) { notify(); }
2909 };
2910
2911 try {
2912 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002913
2914 // First collect all of the stacks of the most important pids.
2915 try {
2916 int num = firstPids.size();
2917 for (int i = 0; i < num; i++) {
2918 synchronized (observer) {
2919 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
2920 observer.wait(200); // Wait for write-close, give up after 200msec
2921 }
2922 }
2923 } catch (InterruptedException e) {
2924 Log.wtf(TAG, e);
2925 }
2926
2927 // Next measure CPU usage.
2928 if (processStats != null) {
2929 processStats.init();
2930 System.gc();
2931 processStats.update();
2932 try {
2933 synchronized (processStats) {
2934 processStats.wait(500); // measure over 1/2 second.
2935 }
2936 } catch (InterruptedException e) {
2937 }
2938 processStats.update();
2939
2940 // We'll take the stack crawls of just the top apps using CPU.
2941 final int N = processStats.countWorkingStats();
2942 int numProcs = 0;
2943 for (int i=0; i<N && numProcs<5; i++) {
2944 ProcessStats.Stats stats = processStats.getWorkingStats(i);
2945 if (lastPids.indexOfKey(stats.pid) >= 0) {
2946 numProcs++;
2947 try {
2948 synchronized (observer) {
2949 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
2950 observer.wait(200); // Wait for write-close, give up after 200msec
2951 }
2952 } catch (InterruptedException e) {
2953 Log.wtf(TAG, e);
2954 }
2955
2956 }
Dan Egnor42471dd2010-01-07 17:25:22 -08002957 }
2958 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002959
2960 return tracesFile;
2961
Dan Egnor42471dd2010-01-07 17:25:22 -08002962 } finally {
2963 observer.stopWatching();
2964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 }
2966
Jeff Brown4d94a762010-09-23 11:33:28 -07002967 private final class AppNotResponding implements Runnable {
2968 private final ProcessRecord mApp;
2969 private final String mAnnotation;
2970
2971 public AppNotResponding(ProcessRecord app, String annotation) {
2972 mApp = app;
2973 mAnnotation = annotation;
2974 }
2975
2976 @Override
2977 public void run() {
2978 appNotResponding(mApp, null, null, mAnnotation);
2979 }
2980 }
2981
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002982 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
2983 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002984 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
2985 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
2986
Dianne Hackborn287952c2010-09-22 22:34:31 -07002987 if (mController != null) {
2988 try {
2989 // 0 == continue, -1 = kill process immediately
2990 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
2991 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
2992 } catch (RemoteException e) {
2993 mController = null;
2994 }
2995 }
2996
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07002997 long anrTime = SystemClock.uptimeMillis();
2998 if (MONITOR_CPU_USAGE) {
2999 updateCpuStatsNow();
3000 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003001
3002 synchronized (this) {
3003 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3004 if (mShuttingDown) {
3005 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3006 return;
3007 } else if (app.notResponding) {
3008 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3009 return;
3010 } else if (app.crashing) {
3011 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3012 return;
3013 }
3014
3015 // In case we come through here for the same app before completing
3016 // this one, mark as anring now so we will bail out.
3017 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003018
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003019 // Log the ANR to the event log.
3020 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3021 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003022
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003023 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003024 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003025
3026 int parentPid = app.pid;
3027 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003028 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003029
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003030 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003031
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003032 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3033 ProcessRecord r = mLruProcesses.get(i);
3034 if (r != null && r.thread != null) {
3035 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003036 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3037 if (r.persistent) {
3038 firstPids.add(pid);
3039 } else {
3040 lastPids.put(pid, Boolean.TRUE);
3041 }
3042 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003044 }
3045 }
3046
Dan Egnor42471dd2010-01-07 17:25:22 -08003047 // Log the ANR to the main log.
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003048 StringBuilder info = mStringBuilder;
3049 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003050 info.append("ANR in ").append(app.processName);
3051 if (activity != null && activity.shortComponentName != null) {
3052 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003053 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003054 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003055 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003056 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003058 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003059 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003060 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061
Dianne Hackborn287952c2010-09-22 22:34:31 -07003062 final ProcessStats processStats = new ProcessStats(true);
3063
3064 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
3065
Dan Egnor42471dd2010-01-07 17:25:22 -08003066 String cpuInfo = null;
3067 if (MONITOR_CPU_USAGE) {
3068 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003069 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003070 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003071 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003072 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003073 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003074 }
3075
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003076 info.append(processStats.printCurrentState(anrTime));
3077
Joe Onorato8a9b2202010-02-26 18:56:32 -08003078 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003079 if (tracesFile == null) {
3080 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3081 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3082 }
3083
Jeff Sharkeya353d262011-10-28 11:12:06 -07003084 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3085 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003086
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003087 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003088 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003089 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3090 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003092 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3093 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003094 }
3095 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003096 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 }
3098 }
3099
Dan Egnor42471dd2010-01-07 17:25:22 -08003100 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3101 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3102 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003103
3104 synchronized (this) {
3105 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003106 Slog.w(TAG, "Killing " + app + ": background ANR");
3107 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3108 app.processName, app.setAdj, "background ANR");
3109 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003110 return;
3111 }
3112
3113 // Set the app's notResponding state, and look up the errorReportReceiver
3114 makeAppNotRespondingLocked(app,
3115 activity != null ? activity.shortComponentName : null,
3116 annotation != null ? "ANR " + annotation : "ANR",
3117 info.toString());
3118
3119 // Bring up the infamous App Not Responding dialog
3120 Message msg = Message.obtain();
3121 HashMap map = new HashMap();
3122 msg.what = SHOW_NOT_RESPONDING_MSG;
3123 msg.obj = map;
3124 map.put("app", app);
3125 if (activity != null) {
3126 map.put("activity", activity);
3127 }
3128
3129 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003130 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003131 }
3132
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003133 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3134 if (!mLaunchWarningShown) {
3135 mLaunchWarningShown = true;
3136 mHandler.post(new Runnable() {
3137 @Override
3138 public void run() {
3139 synchronized (ActivityManagerService.this) {
3140 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3141 d.show();
3142 mHandler.postDelayed(new Runnable() {
3143 @Override
3144 public void run() {
3145 synchronized (ActivityManagerService.this) {
3146 d.dismiss();
3147 mLaunchWarningShown = false;
3148 }
3149 }
3150 }, 4000);
3151 }
3152 }
3153 });
3154 }
3155 }
3156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 public boolean clearApplicationUserData(final String packageName,
3158 final IPackageDataObserver observer) {
3159 int uid = Binder.getCallingUid();
3160 int pid = Binder.getCallingPid();
3161 long callingId = Binder.clearCallingIdentity();
3162 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003163 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164 int pkgUid = -1;
3165 synchronized(this) {
3166 try {
3167 pkgUid = pm.getPackageUid(packageName);
3168 } catch (RemoteException e) {
3169 }
3170 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003171 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003172 return false;
3173 }
3174 if (uid == pkgUid || checkComponentPermission(
3175 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003176 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003177 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003178 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003179 } else {
3180 throw new SecurityException(pid+" does not have permission:"+
3181 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3182 "for process:"+packageName);
3183 }
3184 }
3185
3186 try {
3187 //clear application user data
3188 pm.clearApplicationUserData(packageName, observer);
3189 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3190 Uri.fromParts("package", packageName, null));
3191 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003192 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
3193 null, null, 0, null, null, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 } catch (RemoteException e) {
3195 }
3196 } finally {
3197 Binder.restoreCallingIdentity(callingId);
3198 }
3199 return true;
3200 }
3201
Dianne Hackborn03abb812010-01-04 18:43:19 -08003202 public void killBackgroundProcesses(final String packageName) {
3203 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3204 != PackageManager.PERMISSION_GRANTED &&
3205 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3206 != PackageManager.PERMISSION_GRANTED) {
3207 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 + Binder.getCallingPid()
3209 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003210 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003211 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003212 throw new SecurityException(msg);
3213 }
3214
3215 long callingId = Binder.clearCallingIdentity();
3216 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003217 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003218 int pkgUid = -1;
3219 synchronized(this) {
3220 try {
3221 pkgUid = pm.getPackageUid(packageName);
3222 } catch (RemoteException e) {
3223 }
3224 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003225 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003226 return;
3227 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003228 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003229 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3230 }
3231 } finally {
3232 Binder.restoreCallingIdentity(callingId);
3233 }
3234 }
3235
3236 public void killAllBackgroundProcesses() {
3237 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3238 != PackageManager.PERMISSION_GRANTED) {
3239 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3240 + Binder.getCallingPid()
3241 + ", uid=" + Binder.getCallingUid()
3242 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3243 Slog.w(TAG, msg);
3244 throw new SecurityException(msg);
3245 }
3246
3247 long callingId = Binder.clearCallingIdentity();
3248 try {
3249 synchronized(this) {
3250 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3251 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3252 final int NA = apps.size();
3253 for (int ia=0; ia<NA; ia++) {
3254 ProcessRecord app = apps.valueAt(ia);
3255 if (app.persistent) {
3256 // we don't kill persistent processes
3257 continue;
3258 }
3259 if (app.removed) {
3260 procs.add(app);
3261 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3262 app.removed = true;
3263 procs.add(app);
3264 }
3265 }
3266 }
3267
3268 int N = procs.size();
3269 for (int i=0; i<N; i++) {
3270 removeProcessLocked(procs.get(i), false, true, "kill all background");
3271 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003272 }
3273 } finally {
3274 Binder.restoreCallingIdentity(callingId);
3275 }
3276 }
3277
3278 public void forceStopPackage(final String packageName) {
3279 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3280 != PackageManager.PERMISSION_GRANTED) {
3281 String msg = "Permission Denial: forceStopPackage() from pid="
3282 + Binder.getCallingPid()
3283 + ", uid=" + Binder.getCallingUid()
3284 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003285 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003286 throw new SecurityException(msg);
3287 }
3288
3289 long callingId = Binder.clearCallingIdentity();
3290 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003291 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003292 int pkgUid = -1;
3293 synchronized(this) {
3294 try {
3295 pkgUid = pm.getPackageUid(packageName);
3296 } catch (RemoteException e) {
3297 }
3298 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003299 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003300 return;
3301 }
3302 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003303 try {
3304 pm.setPackageStoppedState(packageName, true);
3305 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003306 } catch (IllegalArgumentException e) {
3307 Slog.w(TAG, "Failed trying to unstop package "
3308 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003309 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 }
3311 } finally {
3312 Binder.restoreCallingIdentity(callingId);
3313 }
3314 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003315
3316 /*
3317 * The pkg name and uid have to be specified.
3318 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3319 */
3320 public void killApplicationWithUid(String pkg, int uid) {
3321 if (pkg == null) {
3322 return;
3323 }
3324 // Make sure the uid is valid.
3325 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003326 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003327 return;
3328 }
3329 int callerUid = Binder.getCallingUid();
3330 // Only the system server can kill an application
3331 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003332 // Post an aysnc message to kill the application
3333 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3334 msg.arg1 = uid;
3335 msg.arg2 = 0;
3336 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003337 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003338 } else {
3339 throw new SecurityException(callerUid + " cannot kill pkg: " +
3340 pkg);
3341 }
3342 }
3343
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003344 public void closeSystemDialogs(String reason) {
3345 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003346 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003347 if (reason != null) {
3348 intent.putExtra("reason", reason);
3349 }
3350
3351 final int uid = Binder.getCallingUid();
3352 final long origId = Binder.clearCallingIdentity();
3353 synchronized (this) {
3354 int i = mWatchers.beginBroadcast();
3355 while (i > 0) {
3356 i--;
3357 IActivityWatcher w = mWatchers.getBroadcastItem(i);
3358 if (w != null) {
3359 try {
3360 w.closingSystemDialogs(reason);
3361 } catch (RemoteException e) {
3362 }
3363 }
3364 }
3365 mWatchers.finishBroadcast();
3366
Dianne Hackbornffa42482009-09-23 22:20:11 -07003367 mWindowManager.closeSystemDialogs(reason);
3368
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003369 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
3370 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003371 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003372 r.stack.finishActivityLocked(r, i,
Dianne Hackbornffa42482009-09-23 22:20:11 -07003373 Activity.RESULT_CANCELED, null, "close-sys");
3374 }
3375 }
3376
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003377 broadcastIntentLocked(null, null, intent, null,
3378 null, 0, null, null, null, false, false, -1, uid);
3379 }
3380 Binder.restoreCallingIdentity(origId);
3381 }
3382
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003383 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003384 throws RemoteException {
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003385 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3386 for (int i=pids.length-1; i>=0; i--) {
3387 infos[i] = new Debug.MemoryInfo();
3388 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003389 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003390 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003391 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003392
Dianne Hackbornb437e092011-08-05 17:50:29 -07003393 public long[] getProcessPss(int[] pids) throws RemoteException {
3394 long[] pss = new long[pids.length];
3395 for (int i=pids.length-1; i>=0; i--) {
3396 pss[i] = Debug.getPss(pids[i]);
3397 }
3398 return pss;
3399 }
3400
Christopher Tate5e1ab332009-09-01 20:32:49 -07003401 public void killApplicationProcess(String processName, int uid) {
3402 if (processName == null) {
3403 return;
3404 }
3405
3406 int callerUid = Binder.getCallingUid();
3407 // Only the system server can kill an application
3408 if (callerUid == Process.SYSTEM_UID) {
3409 synchronized (this) {
3410 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003411 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003412 try {
3413 app.thread.scheduleSuicide();
3414 } catch (RemoteException e) {
3415 // If the other end already died, then our work here is done.
3416 }
3417 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003418 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003419 + processName + " / " + uid);
3420 }
3421 }
3422 } else {
3423 throw new SecurityException(callerUid + " cannot kill app process: " +
3424 processName);
3425 }
3426 }
3427
Dianne Hackborn03abb812010-01-04 18:43:19 -08003428 private void forceStopPackageLocked(final String packageName, int uid) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003429 forceStopPackageLocked(packageName, uid, false, false, true, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003430 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3431 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003432 if (!mProcessesReady) {
3433 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 intent.putExtra(Intent.EXTRA_UID, uid);
3436 broadcastIntentLocked(null, null, intent,
3437 null, null, 0, null, null, null,
3438 false, false, MY_PID, Process.SYSTEM_UID);
3439 }
3440
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003441 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003442 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003443 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003444 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445
Dianne Hackborn03abb812010-01-04 18:43:19 -08003446 // Remove all processes this package may have touched: all with the
3447 // same UID (except for the system or root user), and all whose name
3448 // matches the package name.
3449 final String procNamePrefix = packageName + ":";
3450 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3451 final int NA = apps.size();
3452 for (int ia=0; ia<NA; ia++) {
3453 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003454 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003455 // we don't kill persistent processes
3456 continue;
3457 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003458 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003459 if (doit) {
3460 procs.add(app);
3461 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003462 } else if ((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
3463 || app.processName.equals(packageName)
3464 || app.processName.startsWith(procNamePrefix)) {
3465 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003466 if (!doit) {
3467 return true;
3468 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003469 app.removed = true;
3470 procs.add(app);
3471 }
3472 }
3473 }
3474 }
3475
3476 int N = procs.size();
3477 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003478 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003479 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003480 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003481 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003482
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003483 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003484 boolean callerWillRestart, boolean purgeCache, boolean doit,
3485 boolean evenPersistent) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003486 int i;
3487 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 if (uid < 0) {
3490 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003491 uid = AppGlobals.getPackageManager().getPackageUid(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492 } catch (RemoteException e) {
3493 }
3494 }
3495
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003496 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003497 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003498
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003499 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3500 while (badApps.hasNext()) {
3501 SparseArray<Long> ba = badApps.next();
3502 if (ba.get(uid) != null) {
3503 badApps.remove();
3504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003505 }
3506 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003507
3508 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003509 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003510
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003511 TaskRecord lastTask = null;
3512 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003513 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003514 final boolean samePackage = r.packageName.equals(name);
3515 if ((samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003516 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003517 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003518 if (r.finishing) {
3519 // If this activity is just finishing, then it is not
3520 // interesting as far as something to stop.
3521 continue;
3522 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003523 return true;
3524 }
3525 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003526 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003527 if (samePackage) {
3528 if (r.app != null) {
3529 r.app.removed = true;
3530 }
3531 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003533 lastTask = r.task;
3534 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
3535 null, "force-stop")) {
3536 i--;
3537 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 }
3539 }
3540
3541 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3542 for (ServiceRecord service : mServices.values()) {
Christopher Tate064d8422011-07-26 15:38:07 -07003543 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003544 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003545 if (!doit) {
3546 return true;
3547 }
3548 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003549 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003550 if (service.app != null) {
3551 service.app.removed = true;
3552 }
3553 service.app = null;
3554 services.add(service);
3555 }
3556 }
3557
3558 N = services.size();
3559 for (i=0; i<N; i++) {
3560 bringDownServiceLocked(services.get(i), true);
3561 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003562
3563 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
3564 for (ContentProviderRecord provider : mProvidersByClass.values()) {
3565 if (provider.info.packageName.equals(name)
3566 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3567 if (!doit) {
3568 return true;
3569 }
3570 didSomething = true;
3571 providers.add(provider);
3572 }
3573 }
3574
3575 N = providers.size();
3576 for (i=0; i<N; i++) {
3577 removeDyingProviderLocked(null, providers.get(i));
3578 }
3579
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003580 if (doit) {
3581 if (purgeCache) {
3582 AttributeCache ac = AttributeCache.instance();
3583 if (ac != null) {
3584 ac.removePackage(name);
3585 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003586 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003587 if (mBooted) {
3588 mMainStack.resumeTopActivityLocked(null);
3589 mMainStack.scheduleIdleLocked();
3590 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003591 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003592
3593 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 }
3595
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003596 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003597 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 final String name = app.processName;
3599 final int uid = app.info.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003600 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003601 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 + "/" + uid + ")");
3603
3604 mProcessNames.remove(name, uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003605 if (mHeavyWeightProcess == app) {
3606 mHeavyWeightProcess = null;
3607 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3608 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609 boolean needRestart = false;
3610 if (app.pid > 0 && app.pid != MY_PID) {
3611 int pid = app.pid;
3612 synchronized (mPidsSelfLocked) {
3613 mPidsSelfLocked.remove(pid);
3614 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3615 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003616 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003617 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003618 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003619 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620
3621 if (app.persistent) {
3622 if (!callerWillRestart) {
3623 addAppLocked(app.info);
3624 } else {
3625 needRestart = true;
3626 }
3627 }
3628 } else {
3629 mRemovedProcesses.add(app);
3630 }
3631
3632 return needRestart;
3633 }
3634
3635 private final void processStartTimedOutLocked(ProcessRecord app) {
3636 final int pid = app.pid;
3637 boolean gone = false;
3638 synchronized (mPidsSelfLocked) {
3639 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3640 if (knownApp != null && knownApp.thread == null) {
3641 mPidsSelfLocked.remove(pid);
3642 gone = true;
3643 }
3644 }
3645
3646 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003647 Slog.w(TAG, "Process " + app + " failed to attach");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003648 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.info.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003649 app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003650 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003651 if (mHeavyWeightProcess == app) {
3652 mHeavyWeightProcess = null;
3653 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3654 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003655 // Take care of any launching providers waiting for this process.
3656 checkAppInLaunchingProvidersLocked(app, true);
3657 // Take care of any services that are waiting for the process.
3658 for (int i=0; i<mPendingServices.size(); i++) {
3659 ServiceRecord sr = mPendingServices.get(i);
3660 if (app.info.uid == sr.appInfo.uid
3661 && app.processName.equals(sr.processName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003662 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003663 mPendingServices.remove(i);
3664 i--;
3665 bringDownServiceLocked(sr, true);
3666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003668 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3669 app.processName, app.setAdj, "start timeout");
3670 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003671 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003672 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003673 try {
3674 IBackupManager bm = IBackupManager.Stub.asInterface(
3675 ServiceManager.getService(Context.BACKUP_SERVICE));
3676 bm.agentDisconnected(app.info.packageName);
3677 } catch (RemoteException e) {
3678 // Can't happen; the backup manager is local
3679 }
3680 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003681 if (mPendingBroadcast != null && mPendingBroadcast.curApp.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003682 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003683 mPendingBroadcast.state = BroadcastRecord.IDLE;
3684 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003685 mPendingBroadcast = null;
3686 scheduleBroadcastsLocked();
3687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003689 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 }
3691 }
3692
3693 private final boolean attachApplicationLocked(IApplicationThread thread,
3694 int pid) {
3695
3696 // Find the application record that is being attached... either via
3697 // the pid if we are running in multiple processes, or just pull the
3698 // next app record if we are emulating process with anonymous threads.
3699 ProcessRecord app;
3700 if (pid != MY_PID && pid >= 0) {
3701 synchronized (mPidsSelfLocked) {
3702 app = mPidsSelfLocked.get(pid);
3703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 } else {
3705 app = null;
3706 }
3707
3708 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003709 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003711 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003712 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003713 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 } else {
3715 try {
3716 thread.scheduleExit();
3717 } catch (Exception e) {
3718 // Ignore exceptions.
3719 }
3720 }
3721 return false;
3722 }
3723
3724 // If this application record is still attached to a previous
3725 // process, clean it up now.
3726 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003727 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 }
3729
3730 // Tell the process all about itself.
3731
Joe Onorato8a9b2202010-02-26 18:56:32 -08003732 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003733 TAG, "Binding process pid " + pid + " to record " + app);
3734
3735 String processName = app.processName;
3736 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003737 AppDeathRecipient adr = new AppDeathRecipient(
3738 app, pid, thread);
3739 thread.asBinder().linkToDeath(adr, 0);
3740 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003741 } catch (RemoteException e) {
3742 app.resetPackageList();
3743 startProcessLocked(app, "link fail", processName);
3744 return false;
3745 }
3746
Doug Zongker2bec3d42009-12-04 12:52:44 -08003747 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748
3749 app.thread = thread;
3750 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003751 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3752 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 app.forcingToForeground = null;
3754 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003755 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003756 app.debugging = false;
3757
3758 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3759
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003760 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003761 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003763 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003764 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003765 }
3766
Joe Onorato8a9b2202010-02-26 18:56:32 -08003767 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003768 TAG, "New app record " + app
3769 + " thread=" + thread.asBinder() + " pid=" + pid);
3770 try {
3771 int testMode = IApplicationThread.DEBUG_OFF;
3772 if (mDebugApp != null && mDebugApp.equals(processName)) {
3773 testMode = mWaitForDebugger
3774 ? IApplicationThread.DEBUG_WAIT
3775 : IApplicationThread.DEBUG_ON;
3776 app.debugging = true;
3777 if (mDebugTransient) {
3778 mDebugApp = mOrigDebugApp;
3779 mWaitForDebugger = mOrigWaitForDebugger;
3780 }
3781 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003782 String profileFile = app.instrumentationProfileFile;
3783 ParcelFileDescriptor profileFd = null;
3784 boolean profileAutoStop = false;
3785 if (mProfileApp != null && mProfileApp.equals(processName)) {
3786 mProfileProc = app;
3787 profileFile = mProfileFile;
3788 profileFd = mProfileFd;
3789 profileAutoStop = mAutoStopProfiler;
3790 }
3791
Christopher Tate181fafa2009-05-14 11:12:14 -07003792 // If the app is being launched for restore or full backup, set it up specially
3793 boolean isRestrictedBackupMode = false;
3794 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
3795 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07003796 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07003797 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
3798 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003799
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07003800 ensurePackageDexOpt(app.instrumentationInfo != null
3801 ? app.instrumentationInfo.packageName
3802 : app.info.packageName);
3803 if (app.instrumentationClass != null) {
3804 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003805 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08003806 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003807 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003808 ApplicationInfo appInfo = app.instrumentationInfo != null
3809 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07003810 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003811 if (profileFd != null) {
3812 profileFd = profileFd.dup();
3813 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003814 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003815 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003816 app.instrumentationArguments, app.instrumentationWatcher, testMode,
Dianne Hackborn5d927c22011-09-02 12:22:18 -07003817 isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08003818 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003819 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003820 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003821 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003822 } catch (Exception e) {
3823 // todo: Yikes! What should we do? For now we will try to
3824 // start another process, but that could easily get us in
3825 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08003826 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003827
3828 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003829 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003830 startProcessLocked(app, "bind fail", processName);
3831 return false;
3832 }
3833
3834 // Remove this record from the list of starting applications.
3835 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003836 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
3837 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003838 mProcessesOnHold.remove(app);
3839
3840 boolean badApp = false;
3841 boolean didSomething = false;
3842
3843 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003844 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07003845 if (hr != null && normalMode) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003846 if (hr.app == null && app.info.uid == hr.info.applicationInfo.uid
3847 && processName.equals(hr.processName)) {
3848 try {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003849 if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 didSomething = true;
3851 }
3852 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003853 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003854 + hr.intent.getComponent().flattenToShortString(), e);
3855 badApp = true;
3856 }
3857 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003858 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003859 }
3860 }
3861
3862 // Find any services that should be running in this process...
3863 if (!badApp && mPendingServices.size() > 0) {
3864 ServiceRecord sr = null;
3865 try {
3866 for (int i=0; i<mPendingServices.size(); i++) {
3867 sr = mPendingServices.get(i);
3868 if (app.info.uid != sr.appInfo.uid
3869 || !processName.equals(sr.processName)) {
3870 continue;
3871 }
3872
3873 mPendingServices.remove(i);
3874 i--;
3875 realStartServiceLocked(sr, app);
3876 didSomething = true;
3877 }
3878 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003879 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003880 + sr.shortName, e);
3881 badApp = true;
3882 }
3883 }
3884
3885 // Check if the next broadcast receiver is in this process...
3886 BroadcastRecord br = mPendingBroadcast;
3887 if (!badApp && br != null && br.curApp == app) {
3888 try {
3889 mPendingBroadcast = null;
3890 processCurBroadcastLocked(br, app);
3891 didSomething = true;
3892 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003893 Slog.w(TAG, "Exception in new application when starting receiver "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 + br.curComponent.flattenToShortString(), e);
3895 badApp = true;
Jeff Brown4d94a762010-09-23 11:33:28 -07003896 logBroadcastReceiverDiscardLocked(br);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003897 finishReceiverLocked(br.receiver, br.resultCode, br.resultData,
3898 br.resultExtras, br.resultAbort, true);
3899 scheduleBroadcastsLocked();
Magnus Edlund7bb25812010-02-24 15:45:06 +01003900 // We need to reset the state if we fails to start the receiver.
3901 br.state = BroadcastRecord.IDLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 }
3903 }
3904
Christopher Tate181fafa2009-05-14 11:12:14 -07003905 // Check whether the next backup agent is in this process...
3906 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.info.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003907 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07003908 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07003909 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003910 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
3911 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
3912 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07003913 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003914 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07003915 e.printStackTrace();
3916 }
3917 }
3918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003919 if (badApp) {
3920 // todo: Also need to kill application to deal with all
3921 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003922 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003923 return false;
3924 }
3925
3926 if (!didSomething) {
3927 updateOomAdjLocked();
3928 }
3929
3930 return true;
3931 }
3932
3933 public final void attachApplication(IApplicationThread thread) {
3934 synchronized (this) {
3935 int callingPid = Binder.getCallingPid();
3936 final long origId = Binder.clearCallingIdentity();
3937 attachApplicationLocked(thread, callingPid);
3938 Binder.restoreCallingIdentity(origId);
3939 }
3940 }
3941
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003942 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07003944 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
3945 if (stopProfiling) {
3946 synchronized (this) {
3947 if (mProfileProc == r.app) {
3948 if (mProfileFd != null) {
3949 try {
3950 mProfileFd.close();
3951 } catch (IOException e) {
3952 }
3953 clearProfilerLocked();
3954 }
3955 }
3956 }
3957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003958 Binder.restoreCallingIdentity(origId);
3959 }
3960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08003962 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003963 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003964 mWindowManager.enableScreenAfterBoot();
3965 }
3966
Dianne Hackborn661cd522011-08-22 00:26:20 -07003967 public void showBootMessage(final CharSequence msg, final boolean always) {
3968 mWindowManager.showBootMessage(msg, always);
3969 }
3970
Dianne Hackborn90c52de2011-09-23 12:57:44 -07003971 public void dismissKeyguardOnNextActivity() {
3972 synchronized (this) {
3973 mMainStack.dismissKeyguardOnNextActivityLocked();
3974 }
3975 }
3976
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003977 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003978 IntentFilter pkgFilter = new IntentFilter();
3979 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
3980 pkgFilter.addDataScheme("package");
3981 mContext.registerReceiver(new BroadcastReceiver() {
3982 @Override
3983 public void onReceive(Context context, Intent intent) {
3984 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
3985 if (pkgs != null) {
3986 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003987 synchronized (ActivityManagerService.this) {
Christopher Tate3dacd842011-08-19 14:56:15 -07003988 if (forceStopPackageLocked(pkg, -1, false, false, false, false)) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07003989 setResultCode(Activity.RESULT_OK);
3990 return;
3991 }
3992 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003993 }
3994 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003995 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003996 }, pkgFilter);
3997
3998 synchronized (this) {
3999 // Ensure that any processes we had put on hold are now started
4000 // up.
4001 final int NP = mProcessesOnHold.size();
4002 if (NP > 0) {
4003 ArrayList<ProcessRecord> procs =
4004 new ArrayList<ProcessRecord>(mProcessesOnHold);
4005 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004006 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4007 + procs.get(ip));
4008 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004009 }
4010 }
4011
4012 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004013 // Start looking for apps that are abusing wake locks.
4014 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004015 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004016 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004017 SystemProperties.set("sys.boot_completed", "1");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004018 broadcastIntentLocked(null, null,
4019 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4020 null, null, 0, null, null,
4021 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
4022 false, false, MY_PID, Process.SYSTEM_UID);
4023 }
4024 }
4025 }
4026
4027 final void ensureBootCompleted() {
4028 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004029 boolean enableScreen;
4030 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004031 booting = mBooting;
4032 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004033 enableScreen = !mBooted;
4034 mBooted = true;
4035 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004036
4037 if (booting) {
4038 finishBooting();
4039 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004040
4041 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004042 enableScreenAfterBoot();
4043 }
4044 }
4045
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004046 public final void activityPaused(IBinder token) {
4047 final long origId = Binder.clearCallingIdentity();
4048 mMainStack.activityPaused(token, false);
4049 Binder.restoreCallingIdentity(origId);
4050 }
4051
4052 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4053 CharSequence description) {
4054 if (localLOGV) Slog.v(
4055 TAG, "Activity stopped: token=" + token);
4056
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004057 // Refuse possible leaked file descriptors
4058 if (icicle != null && icicle.hasFileDescriptors()) {
4059 throw new IllegalArgumentException("File descriptors passed in Bundle");
4060 }
4061
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004062 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063
4064 final long origId = Binder.clearCallingIdentity();
4065
4066 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004067 r = mMainStack.isInStackLocked(token);
4068 if (r != null) {
4069 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004070 }
4071 }
4072
4073 if (r != null) {
4074 sendPendingThumbnail(r, null, null, null, false);
4075 }
4076
4077 trimApplications();
4078
4079 Binder.restoreCallingIdentity(origId);
4080 }
4081
4082 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004083 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004084 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 }
4086
4087 public String getCallingPackage(IBinder token) {
4088 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004089 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004090 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 }
4092 }
4093
4094 public ComponentName getCallingActivity(IBinder token) {
4095 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004096 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004097 return r != null ? r.intent.getComponent() : null;
4098 }
4099 }
4100
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004101 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004102 ActivityRecord r = mMainStack.isInStackLocked(token);
4103 if (r == null) {
4104 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004105 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004106 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004107 }
4108
4109 public ComponentName getActivityClassForToken(IBinder token) {
4110 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004111 ActivityRecord r = mMainStack.isInStackLocked(token);
4112 if (r == null) {
4113 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004114 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004115 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 }
4117 }
4118
4119 public String getPackageForToken(IBinder token) {
4120 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004121 ActivityRecord r = mMainStack.isInStackLocked(token);
4122 if (r == null) {
4123 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004124 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004125 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 }
4127 }
4128
4129 public IIntentSender getIntentSender(int type,
4130 String packageName, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004131 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004132 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004133 if (intents != null) {
4134 if (intents.length < 1) {
4135 throw new IllegalArgumentException("Intents array length must be >= 1");
4136 }
4137 for (int i=0; i<intents.length; i++) {
4138 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004139 if (intent != null) {
4140 if (intent.hasFileDescriptors()) {
4141 throw new IllegalArgumentException("File descriptors passed in Intent");
4142 }
4143 if (type == INTENT_SENDER_BROADCAST &&
4144 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4145 throw new IllegalArgumentException(
4146 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4147 }
4148 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004149 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004150 }
4151 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004152 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004153 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004154 }
4155 }
4156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004157 synchronized(this) {
4158 int callingUid = Binder.getCallingUid();
4159 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004160 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004161 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004162 .getPackageUid(packageName);
4163 if (uid != Binder.getCallingUid()) {
4164 String msg = "Permission Denial: getIntentSender() from pid="
4165 + Binder.getCallingPid()
4166 + ", uid=" + Binder.getCallingUid()
4167 + ", (need uid=" + uid + ")"
4168 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004169 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004170 throw new SecurityException(msg);
4171 }
4172 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004173
4174 return getIntentSenderLocked(type, packageName, callingUid,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004175 token, resultWho, requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004177 } catch (RemoteException e) {
4178 throw new SecurityException(e);
4179 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004180 }
4181 }
4182
4183 IIntentSender getIntentSenderLocked(int type,
4184 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004185 int requestCode, Intent[] intents, String[] resolvedTypes, int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004186 ActivityRecord activity = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004187 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004188 activity = mMainStack.isInStackLocked(token);
4189 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004190 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004191 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004192 if (activity.finishing) {
4193 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004195 }
4196
4197 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4198 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4199 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4200 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4201 |PendingIntent.FLAG_UPDATE_CURRENT);
4202
4203 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4204 type, packageName, activity, resultWho,
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004205 requestCode, intents, resolvedTypes, flags);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004206 WeakReference<PendingIntentRecord> ref;
4207 ref = mIntentSenderRecords.get(key);
4208 PendingIntentRecord rec = ref != null ? ref.get() : null;
4209 if (rec != null) {
4210 if (!cancelCurrent) {
4211 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004212 if (rec.key.requestIntent != null) {
4213 rec.key.requestIntent.replaceExtras(intents != null ? intents[0] : null);
4214 }
4215 if (intents != null) {
4216 intents[intents.length-1] = rec.key.requestIntent;
4217 rec.key.allIntents = intents;
4218 rec.key.allResolvedTypes = resolvedTypes;
4219 } else {
4220 rec.key.allIntents = null;
4221 rec.key.allResolvedTypes = null;
4222 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004224 return rec;
4225 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004226 rec.canceled = true;
4227 mIntentSenderRecords.remove(key);
4228 }
4229 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004230 return rec;
4231 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004232 rec = new PendingIntentRecord(this, key, callingUid);
4233 mIntentSenderRecords.put(key, rec.ref);
4234 if (type == INTENT_SENDER_ACTIVITY_RESULT) {
4235 if (activity.pendingResults == null) {
4236 activity.pendingResults
4237 = new HashSet<WeakReference<PendingIntentRecord>>();
4238 }
4239 activity.pendingResults.add(rec.ref);
4240 }
4241 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 }
4243
4244 public void cancelIntentSender(IIntentSender sender) {
4245 if (!(sender instanceof PendingIntentRecord)) {
4246 return;
4247 }
4248 synchronized(this) {
4249 PendingIntentRecord rec = (PendingIntentRecord)sender;
4250 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004251 int uid = AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 .getPackageUid(rec.key.packageName);
4253 if (uid != Binder.getCallingUid()) {
4254 String msg = "Permission Denial: cancelIntentSender() from pid="
4255 + Binder.getCallingPid()
4256 + ", uid=" + Binder.getCallingUid()
4257 + " is not allowed to cancel packges "
4258 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004259 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004260 throw new SecurityException(msg);
4261 }
4262 } catch (RemoteException e) {
4263 throw new SecurityException(e);
4264 }
4265 cancelIntentSenderLocked(rec, true);
4266 }
4267 }
4268
4269 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4270 rec.canceled = true;
4271 mIntentSenderRecords.remove(rec.key);
4272 if (cleanActivity && rec.key.activity != null) {
4273 rec.key.activity.pendingResults.remove(rec.ref);
4274 }
4275 }
4276
4277 public String getPackageForIntentSender(IIntentSender pendingResult) {
4278 if (!(pendingResult instanceof PendingIntentRecord)) {
4279 return null;
4280 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004281 try {
4282 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4283 return res.key.packageName;
4284 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004285 }
4286 return null;
4287 }
4288
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004289 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4290 if (!(pendingResult instanceof PendingIntentRecord)) {
4291 return false;
4292 }
4293 try {
4294 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4295 if (res.key.allIntents == null) {
4296 return false;
4297 }
4298 for (int i=0; i<res.key.allIntents.length; i++) {
4299 Intent intent = res.key.allIntents[i];
4300 if (intent.getPackage() != null && intent.getComponent() != null) {
4301 return false;
4302 }
4303 }
4304 return true;
4305 } catch (ClassCastException e) {
4306 }
4307 return false;
4308 }
4309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004310 public void setProcessLimit(int max) {
4311 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4312 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004313 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004314 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004315 mProcessLimitOverride = max;
4316 }
4317 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 }
4319
4320 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004321 synchronized (this) {
4322 return mProcessLimitOverride;
4323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004324 }
4325
4326 void foregroundTokenDied(ForegroundToken token) {
4327 synchronized (ActivityManagerService.this) {
4328 synchronized (mPidsSelfLocked) {
4329 ForegroundToken cur
4330 = mForegroundProcesses.get(token.pid);
4331 if (cur != token) {
4332 return;
4333 }
4334 mForegroundProcesses.remove(token.pid);
4335 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4336 if (pr == null) {
4337 return;
4338 }
4339 pr.forcingToForeground = null;
4340 pr.foregroundServices = false;
4341 }
4342 updateOomAdjLocked();
4343 }
4344 }
4345
4346 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4347 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4348 "setProcessForeground()");
4349 synchronized(this) {
4350 boolean changed = false;
4351
4352 synchronized (mPidsSelfLocked) {
4353 ProcessRecord pr = mPidsSelfLocked.get(pid);
4354 if (pr == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004355 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 return;
4357 }
4358 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4359 if (oldToken != null) {
4360 oldToken.token.unlinkToDeath(oldToken, 0);
4361 mForegroundProcesses.remove(pid);
4362 pr.forcingToForeground = null;
4363 changed = true;
4364 }
4365 if (isForeground && token != null) {
4366 ForegroundToken newToken = new ForegroundToken() {
4367 public void binderDied() {
4368 foregroundTokenDied(this);
4369 }
4370 };
4371 newToken.pid = pid;
4372 newToken.token = token;
4373 try {
4374 token.linkToDeath(newToken, 0);
4375 mForegroundProcesses.put(pid, newToken);
4376 pr.forcingToForeground = token;
4377 changed = true;
4378 } catch (RemoteException e) {
4379 // If the process died while doing this, we will later
4380 // do the cleanup with the process death link.
4381 }
4382 }
4383 }
4384
4385 if (changed) {
4386 updateOomAdjLocked();
4387 }
4388 }
4389 }
4390
4391 // =========================================================
4392 // PERMISSIONS
4393 // =========================================================
4394
4395 static class PermissionController extends IPermissionController.Stub {
4396 ActivityManagerService mActivityManagerService;
4397 PermissionController(ActivityManagerService activityManagerService) {
4398 mActivityManagerService = activityManagerService;
4399 }
4400
4401 public boolean checkPermission(String permission, int pid, int uid) {
4402 return mActivityManagerService.checkPermission(permission, pid,
4403 uid) == PackageManager.PERMISSION_GRANTED;
4404 }
4405 }
4406
4407 /**
4408 * This can be called with or without the global lock held.
4409 */
4410 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004411 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004412 // We might be performing an operation on behalf of an indirect binder
4413 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4414 // client identity accordingly before proceeding.
4415 Identity tlsIdentity = sCallerIdentity.get();
4416 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004417 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004418 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4419 uid = tlsIdentity.uid;
4420 pid = tlsIdentity.pid;
4421 }
4422
4423 // Root, system server and our own process get to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004424 if (uid == 0 || uid == Process.SYSTEM_UID || pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004425 return PackageManager.PERMISSION_GRANTED;
4426 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004427 // If there is a uid that owns whatever is being accessed, it has
4428 // blanket access to it regardless of the permissions it requires.
4429 if (owningUid >= 0 && uid == owningUid) {
4430 return PackageManager.PERMISSION_GRANTED;
4431 }
4432 // If the target is not exported, then nobody else can get to it.
4433 if (!exported) {
4434 Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004435 return PackageManager.PERMISSION_DENIED;
4436 }
4437 if (permission == null) {
4438 return PackageManager.PERMISSION_GRANTED;
4439 }
4440 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004441 return AppGlobals.getPackageManager()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004442 .checkUidPermission(permission, uid);
4443 } catch (RemoteException e) {
4444 // Should never happen, but if it does... deny!
Joe Onorato8a9b2202010-02-26 18:56:32 -08004445 Slog.e(TAG, "PackageManager is dead?!?", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004446 }
4447 return PackageManager.PERMISSION_DENIED;
4448 }
4449
4450 /**
4451 * As the only public entry point for permissions checking, this method
4452 * can enforce the semantic that requesting a check on a null global
4453 * permission is automatically denied. (Internally a null permission
4454 * string is used when calling {@link #checkComponentPermission} in cases
4455 * when only uid-based security is needed.)
4456 *
4457 * This can be called with or without the global lock held.
4458 */
4459 public int checkPermission(String permission, int pid, int uid) {
4460 if (permission == null) {
4461 return PackageManager.PERMISSION_DENIED;
4462 }
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004463 return checkComponentPermission(permission, pid, uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004464 }
4465
4466 /**
4467 * Binder IPC calls go through the public entry point.
4468 * This can be called with or without the global lock held.
4469 */
4470 int checkCallingPermission(String permission) {
4471 return checkPermission(permission,
4472 Binder.getCallingPid(),
4473 Binder.getCallingUid());
4474 }
4475
4476 /**
4477 * This can be called with or without the global lock held.
4478 */
4479 void enforceCallingPermission(String permission, String func) {
4480 if (checkCallingPermission(permission)
4481 == PackageManager.PERMISSION_GRANTED) {
4482 return;
4483 }
4484
4485 String msg = "Permission Denial: " + func + " from pid="
4486 + Binder.getCallingPid()
4487 + ", uid=" + Binder.getCallingUid()
4488 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004489 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004490 throw new SecurityException(msg);
4491 }
4492
4493 private final boolean checkHoldingPermissionsLocked(IPackageManager pm,
Dianne Hackborn48058e82010-09-27 16:53:23 -07004494 ProviderInfo pi, Uri uri, int uid, int modeFlags) {
4495 boolean readPerm = (modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4496 boolean writePerm = (modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
4497 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4498 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 try {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004500 // Is the component private from the target uid?
4501 final boolean prv = !pi.exported && pi.applicationInfo.uid != uid;
4502
4503 // Acceptable if the there is no read permission needed from the
4504 // target or the target is holding the read permission.
4505 if (!readPerm) {
4506 if ((!prv && pi.readPermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 (pm.checkUidPermission(pi.readPermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004508 == PackageManager.PERMISSION_GRANTED)) {
4509 readPerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 }
4511 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004512
4513 // Acceptable if the there is no write permission needed from the
4514 // target or the target is holding the read permission.
4515 if (!writePerm) {
4516 if (!prv && (pi.writePermission == null) ||
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 (pm.checkUidPermission(pi.writePermission, uid)
Dianne Hackborn48058e82010-09-27 16:53:23 -07004518 == PackageManager.PERMISSION_GRANTED)) {
4519 writePerm = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 }
4521 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004522
4523 // Acceptable if there is a path permission matching the URI that
4524 // the target holds the permission on.
4525 PathPermission[] pps = pi.pathPermissions;
4526 if (pps != null && (!readPerm || !writePerm)) {
4527 final String path = uri.getPath();
4528 int i = pps.length;
4529 while (i > 0 && (!readPerm || !writePerm)) {
4530 i--;
4531 PathPermission pp = pps[i];
4532 if (!readPerm) {
4533 final String pprperm = pp.getReadPermission();
4534 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4535 + pprperm + " for " + pp.getPath()
4536 + ": match=" + pp.match(path)
4537 + " check=" + pm.checkUidPermission(pprperm, uid));
4538 if (pprperm != null && pp.match(path) &&
4539 (pm.checkUidPermission(pprperm, uid)
4540 == PackageManager.PERMISSION_GRANTED)) {
4541 readPerm = true;
4542 }
4543 }
4544 if (!writePerm) {
4545 final String ppwperm = pp.getWritePermission();
4546 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4547 + ppwperm + " for " + pp.getPath()
4548 + ": match=" + pp.match(path)
4549 + " check=" + pm.checkUidPermission(ppwperm, uid));
4550 if (ppwperm != null && pp.match(path) &&
4551 (pm.checkUidPermission(ppwperm, uid)
4552 == PackageManager.PERMISSION_GRANTED)) {
4553 writePerm = true;
4554 }
4555 }
4556 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004557 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004558 } catch (RemoteException e) {
4559 return false;
4560 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004561
4562 return readPerm && writePerm;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004563 }
4564
4565 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4566 int modeFlags) {
4567 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004568 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004569 return true;
4570 }
4571 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4572 if (perms == null) return false;
4573 UriPermission perm = perms.get(uri);
4574 if (perm == null) return false;
4575 return (modeFlags&perm.modeFlags) == modeFlags;
4576 }
4577
4578 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
4579 // Another redirected-binder-call permissions check as in
4580 // {@link checkComponentPermission}.
4581 Identity tlsIdentity = sCallerIdentity.get();
4582 if (tlsIdentity != null) {
4583 uid = tlsIdentity.uid;
4584 pid = tlsIdentity.pid;
4585 }
4586
4587 // Our own process gets to do everything.
4588 if (pid == MY_PID) {
4589 return PackageManager.PERMISSION_GRANTED;
4590 }
4591 synchronized(this) {
4592 return checkUriPermissionLocked(uri, uid, modeFlags)
4593 ? PackageManager.PERMISSION_GRANTED
4594 : PackageManager.PERMISSION_DENIED;
4595 }
4596 }
4597
Dianne Hackborn39792d22010-08-19 18:01:52 -07004598 /**
4599 * Check if the targetPkg can be granted permission to access uri by
4600 * the callingUid using the given modeFlags. Throws a security exception
4601 * if callingUid is not allowed to do this. Returns the uid of the target
4602 * if the URI permission grant should be performed; returns -1 if it is not
4603 * needed (for example targetPkg already has permission to access the URI).
4604 */
4605 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
4606 Uri uri, int modeFlags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004607 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4608 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4609 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004610 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004611 }
4612
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004613 if (targetPkg != null) {
4614 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4615 "Checking grant " + targetPkg + " permission to " + uri);
4616 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004617
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004618 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004619
4620 // If this is not a content: uri, we can't do anything with it.
4621 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004622 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004623 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004624 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004625 }
4626
4627 String name = uri.getAuthority();
4628 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004629 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004630 if (cpr != null) {
4631 pi = cpr.info;
4632 } else {
4633 try {
4634 pi = pm.resolveContentProvider(name,
4635 PackageManager.GET_URI_PERMISSION_PATTERNS);
4636 } catch (RemoteException ex) {
4637 }
4638 }
4639 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004640 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004641 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004642 }
4643
4644 int targetUid;
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004645 if (targetPkg != null) {
4646 try {
4647 targetUid = pm.getPackageUid(targetPkg);
4648 if (targetUid < 0) {
4649 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4650 "Can't grant URI permission no uid for: " + targetPkg);
4651 return -1;
4652 }
4653 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004654 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004655 }
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004656 } else {
4657 targetUid = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004658 }
4659
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004660 if (targetUid >= 0) {
4661 // First... does the target actually need this permission?
4662 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4663 // No need to grant the target this permission.
4664 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4665 "Target " + targetPkg + " already has full permission to " + uri);
4666 return -1;
4667 }
4668 } else {
4669 // First... there is no target package, so can anyone access it?
4670 boolean allowed = pi.exported;
4671 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4672 if (pi.readPermission != null) {
4673 allowed = false;
4674 }
4675 }
4676 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4677 if (pi.writePermission != null) {
4678 allowed = false;
4679 }
4680 }
4681 if (allowed) {
4682 return -1;
4683 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004684 }
4685
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004686 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004687 if (!pi.grantUriPermissions) {
4688 throw new SecurityException("Provider " + pi.packageName
4689 + "/" + pi.name
4690 + " does not allow granting of Uri permissions (uri "
4691 + uri + ")");
4692 }
4693 if (pi.uriPermissionPatterns != null) {
4694 final int N = pi.uriPermissionPatterns.length;
4695 boolean allowed = false;
4696 for (int i=0; i<N; i++) {
4697 if (pi.uriPermissionPatterns[i] != null
4698 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4699 allowed = true;
4700 break;
4701 }
4702 }
4703 if (!allowed) {
4704 throw new SecurityException("Provider " + pi.packageName
4705 + "/" + pi.name
4706 + " does not allow granting of permission to path of Uri "
4707 + uri);
4708 }
4709 }
4710
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004711 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004712 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004713 if (callingUid != Process.myUid()) {
4714 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
4715 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4716 throw new SecurityException("Uid " + callingUid
4717 + " does not have permission to uri " + uri);
4718 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 }
4720 }
4721
Dianne Hackborn39792d22010-08-19 18:01:52 -07004722 return targetUid;
4723 }
4724
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004725 public int checkGrantUriPermission(int callingUid, String targetPkg,
4726 Uri uri, int modeFlags) {
4727 synchronized(this) {
4728 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4729 }
4730 }
4731
Dianne Hackborn39792d22010-08-19 18:01:52 -07004732 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
4733 Uri uri, int modeFlags, UriPermissionOwner owner) {
4734 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4735 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4736 if (modeFlags == 0) {
4737 return;
4738 }
4739
4740 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 // to the uri, and the target doesn't. Let's now give this to
4742 // the target.
4743
Joe Onorato8a9b2202010-02-26 18:56:32 -08004744 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004745 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004747 HashMap<Uri, UriPermission> targetUris
4748 = mGrantedUriPermissions.get(targetUid);
4749 if (targetUris == null) {
4750 targetUris = new HashMap<Uri, UriPermission>();
4751 mGrantedUriPermissions.put(targetUid, targetUris);
4752 }
4753
4754 UriPermission perm = targetUris.get(uri);
4755 if (perm == null) {
4756 perm = new UriPermission(targetUid, uri);
4757 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004758 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004760 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07004761 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08004763 } else {
4764 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4765 perm.readOwners.add(owner);
4766 owner.addReadPermission(perm);
4767 }
4768 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4769 perm.writeOwners.add(owner);
4770 owner.addWritePermission(perm);
4771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004772 }
4773 }
4774
Dianne Hackborn39792d22010-08-19 18:01:52 -07004775 void grantUriPermissionLocked(int callingUid,
4776 String targetPkg, Uri uri, int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004777 if (targetPkg == null) {
4778 throw new NullPointerException("targetPkg");
4779 }
4780
Dianne Hackborn39792d22010-08-19 18:01:52 -07004781 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags);
4782 if (targetUid < 0) {
4783 return;
4784 }
4785
4786 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
4787 }
4788
4789 /**
4790 * Like checkGrantUriPermissionLocked, but takes an Intent.
4791 */
4792 int checkGrantUriPermissionFromIntentLocked(int callingUid,
4793 String targetPkg, Intent intent) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07004794 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07004795 "Checking URI perm to " + (intent != null ? intent.getData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07004796 + " from " + intent + "; flags=0x"
4797 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
4798
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004799 if (targetPkg == null) {
4800 throw new NullPointerException("targetPkg");
4801 }
4802
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004803 if (intent == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004804 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004805 }
4806 Uri data = intent.getData();
4807 if (data == null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004808 return -1;
4809 }
4810 return checkGrantUriPermissionLocked(callingUid, targetPkg, data,
4811 intent.getFlags());
4812 }
4813
4814 /**
4815 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
4816 */
4817 void grantUriPermissionUncheckedFromIntentLocked(int targetUid,
4818 String targetPkg, Intent intent, UriPermissionOwner owner) {
4819 grantUriPermissionUncheckedLocked(targetUid, targetPkg, intent.getData(),
4820 intent.getFlags(), owner);
4821 }
4822
4823 void grantUriPermissionFromIntentLocked(int callingUid,
4824 String targetPkg, Intent intent, UriPermissionOwner owner) {
4825 int targetUid = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg, intent);
4826 if (targetUid < 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004827 return;
4828 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07004829
4830 grantUriPermissionUncheckedFromIntentLocked(targetUid, targetPkg, intent, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004831 }
4832
4833 public void grantUriPermission(IApplicationThread caller, String targetPkg,
4834 Uri uri, int modeFlags) {
4835 synchronized(this) {
4836 final ProcessRecord r = getRecordForAppLocked(caller);
4837 if (r == null) {
4838 throw new SecurityException("Unable to find app for caller "
4839 + caller
4840 + " when granting permission to uri " + uri);
4841 }
4842 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004843 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004844 }
4845 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07004846 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 }
4848
4849 grantUriPermissionLocked(r.info.uid, targetPkg, uri, modeFlags,
4850 null);
4851 }
4852 }
4853
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004854 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004855 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
4856 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
4857 HashMap<Uri, UriPermission> perms
4858 = mGrantedUriPermissions.get(perm.uid);
4859 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004860 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004861 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004862 perms.remove(perm.uri);
4863 if (perms.size() == 0) {
4864 mGrantedUriPermissions.remove(perm.uid);
4865 }
4866 }
4867 }
4868 }
4869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 private void revokeUriPermissionLocked(int callingUid, Uri uri,
4871 int modeFlags) {
4872 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4873 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4874 if (modeFlags == 0) {
4875 return;
4876 }
4877
Joe Onorato8a9b2202010-02-26 18:56:32 -08004878 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004879 "Revoking all granted permissions to " + uri);
4880
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004881 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882
4883 final String authority = uri.getAuthority();
4884 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004885 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 if (cpr != null) {
4887 pi = cpr.info;
4888 } else {
4889 try {
4890 pi = pm.resolveContentProvider(authority,
4891 PackageManager.GET_URI_PERMISSION_PATTERNS);
4892 } catch (RemoteException ex) {
4893 }
4894 }
4895 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004896 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897 return;
4898 }
4899
4900 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07004901 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004902 // Right now, if you are not the original owner of the permission,
4903 // you are not allowed to revoke it.
4904 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
4905 throw new SecurityException("Uid " + callingUid
4906 + " does not have permission to uri " + uri);
4907 //}
4908 }
4909
4910 // Go through all of the permissions and remove any that match.
4911 final List<String> SEGMENTS = uri.getPathSegments();
4912 if (SEGMENTS != null) {
4913 final int NS = SEGMENTS.size();
4914 int N = mGrantedUriPermissions.size();
4915 for (int i=0; i<N; i++) {
4916 HashMap<Uri, UriPermission> perms
4917 = mGrantedUriPermissions.valueAt(i);
4918 Iterator<UriPermission> it = perms.values().iterator();
4919 toploop:
4920 while (it.hasNext()) {
4921 UriPermission perm = it.next();
4922 Uri targetUri = perm.uri;
4923 if (!authority.equals(targetUri.getAuthority())) {
4924 continue;
4925 }
4926 List<String> targetSegments = targetUri.getPathSegments();
4927 if (targetSegments == null) {
4928 continue;
4929 }
4930 if (targetSegments.size() < NS) {
4931 continue;
4932 }
4933 for (int j=0; j<NS; j++) {
4934 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
4935 continue toploop;
4936 }
4937 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004938 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004939 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004940 perm.clearModes(modeFlags);
4941 if (perm.modeFlags == 0) {
4942 it.remove();
4943 }
4944 }
4945 if (perms.size() == 0) {
4946 mGrantedUriPermissions.remove(
4947 mGrantedUriPermissions.keyAt(i));
4948 N--;
4949 i--;
4950 }
4951 }
4952 }
4953 }
4954
4955 public void revokeUriPermission(IApplicationThread caller, Uri uri,
4956 int modeFlags) {
4957 synchronized(this) {
4958 final ProcessRecord r = getRecordForAppLocked(caller);
4959 if (r == null) {
4960 throw new SecurityException("Unable to find app for caller "
4961 + caller
4962 + " when revoking permission to uri " + uri);
4963 }
4964 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004965 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004966 return;
4967 }
4968
4969 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4970 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4971 if (modeFlags == 0) {
4972 return;
4973 }
4974
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004975 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004976
4977 final String authority = uri.getAuthority();
4978 ProviderInfo pi = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004979 ContentProviderRecord cpr = mProvidersByName.get(authority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 if (cpr != null) {
4981 pi = cpr.info;
4982 } else {
4983 try {
4984 pi = pm.resolveContentProvider(authority,
4985 PackageManager.GET_URI_PERMISSION_PATTERNS);
4986 } catch (RemoteException ex) {
4987 }
4988 }
4989 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004990 Slog.w(TAG, "No content provider found for permission revoke: "
4991 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004992 return;
4993 }
4994
4995 revokeUriPermissionLocked(r.info.uid, uri, modeFlags);
4996 }
4997 }
4998
Dianne Hackborn7e269642010-08-25 19:50:20 -07004999 @Override
5000 public IBinder newUriPermissionOwner(String name) {
5001 synchronized(this) {
5002 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5003 return owner.getExternalTokenLocked();
5004 }
5005 }
5006
5007 @Override
5008 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5009 Uri uri, int modeFlags) {
5010 synchronized(this) {
5011 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5012 if (owner == null) {
5013 throw new IllegalArgumentException("Unknown owner: " + token);
5014 }
5015 if (fromUid != Binder.getCallingUid()) {
5016 if (Binder.getCallingUid() != Process.myUid()) {
5017 // Only system code can grant URI permissions on behalf
5018 // of other users.
5019 throw new SecurityException("nice try");
5020 }
5021 }
5022 if (targetPkg == null) {
5023 throw new IllegalArgumentException("null target");
5024 }
5025 if (uri == null) {
5026 throw new IllegalArgumentException("null uri");
5027 }
5028
5029 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5030 }
5031 }
5032
5033 @Override
5034 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5035 synchronized(this) {
5036 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5037 if (owner == null) {
5038 throw new IllegalArgumentException("Unknown owner: " + token);
5039 }
5040
5041 if (uri == null) {
5042 owner.removeUriPermissionsLocked(mode);
5043 } else {
5044 owner.removeUriPermissionLocked(uri, mode);
5045 }
5046 }
5047 }
5048
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005049 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5050 synchronized (this) {
5051 ProcessRecord app =
5052 who != null ? getRecordForAppLocked(who) : null;
5053 if (app == null) return;
5054
5055 Message msg = Message.obtain();
5056 msg.what = WAIT_FOR_DEBUGGER_MSG;
5057 msg.obj = app;
5058 msg.arg1 = waiting ? 1 : 0;
5059 mHandler.sendMessage(msg);
5060 }
5061 }
5062
5063 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005064 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5065 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005066 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005067 outInfo.threshold = homeAppMem;
5068 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5069 outInfo.hiddenAppThreshold = hiddenAppMem;
5070 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005071 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005072 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5073 ProcessList.VISIBLE_APP_ADJ);
5074 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5075 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005076 }
5077
5078 // =========================================================
5079 // TASK MANAGEMENT
5080 // =========================================================
5081
5082 public List getTasks(int maxNum, int flags,
5083 IThumbnailReceiver receiver) {
5084 ArrayList list = new ArrayList();
5085
5086 PendingThumbnailsRecord pending = null;
5087 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005088 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005089
5090 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005091 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005092 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5093 + ", receiver=" + receiver);
5094
5095 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5096 != PackageManager.PERMISSION_GRANTED) {
5097 if (receiver != null) {
5098 // If the caller wants to wait for pending thumbnails,
5099 // it ain't gonna get them.
5100 try {
5101 receiver.finished();
5102 } catch (RemoteException ex) {
5103 }
5104 }
5105 String msg = "Permission Denial: getTasks() from pid="
5106 + Binder.getCallingPid()
5107 + ", uid=" + Binder.getCallingUid()
5108 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005109 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005110 throw new SecurityException(msg);
5111 }
5112
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005113 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005114 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005115 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005116 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005117 TaskRecord curTask = null;
5118 int numActivities = 0;
5119 int numRunning = 0;
5120 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005121 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005122 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005123 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124
5125 // Initialize state for next task if needed.
5126 if (top == null ||
5127 (top.state == ActivityState.INITIALIZING
5128 && top.task == r.task)) {
5129 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005130 curTask = r.task;
5131 numActivities = numRunning = 0;
5132 }
5133
5134 // Add 'r' into the current task.
5135 numActivities++;
5136 if (r.app != null && r.app.thread != null) {
5137 numRunning++;
5138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005139
Joe Onorato8a9b2202010-02-26 18:56:32 -08005140 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005141 TAG, r.intent.getComponent().flattenToShortString()
5142 + ": task=" + r.task);
5143
5144 // If the next one is a different task, generate a new
5145 // TaskInfo entry for what we have.
5146 if (next == null || next.task != curTask) {
5147 ActivityManager.RunningTaskInfo ci
5148 = new ActivityManager.RunningTaskInfo();
5149 ci.id = curTask.taskId;
5150 ci.baseActivity = r.intent.getComponent();
5151 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005152 if (top.thumbHolder != null) {
5153 ci.description = top.thumbHolder.lastDescription;
5154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005155 ci.numActivities = numActivities;
5156 ci.numRunning = numRunning;
5157 //System.out.println(
5158 // "#" + maxNum + ": " + " descr=" + ci.description);
5159 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005160 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005161 TAG, "State=" + top.state + "Idle=" + top.idle
5162 + " app=" + top.app
5163 + " thr=" + (top.app != null ? top.app.thread : null));
5164 if (top.state == ActivityState.RESUMED
5165 || top.state == ActivityState.PAUSING) {
5166 if (top.idle && top.app != null
5167 && top.app.thread != null) {
5168 topRecord = top;
5169 topThumbnail = top.app.thread;
5170 } else {
5171 top.thumbnailNeeded = true;
5172 }
5173 }
5174 if (pending == null) {
5175 pending = new PendingThumbnailsRecord(receiver);
5176 }
5177 pending.pendingRecords.add(top);
5178 }
5179 list.add(ci);
5180 maxNum--;
5181 top = null;
5182 }
5183 }
5184
5185 if (pending != null) {
5186 mPendingThumbnails.add(pending);
5187 }
5188 }
5189
Joe Onorato8a9b2202010-02-26 18:56:32 -08005190 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005191
5192 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005193 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005194 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005195 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005197 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005198 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005199 }
5200 }
5201
5202 if (pending == null && receiver != null) {
5203 // In this case all thumbnails were available and the client
5204 // is being asked to be told when the remaining ones come in...
5205 // which is unusually, since the top-most currently running
5206 // activity should never have a canned thumbnail! Oh well.
5207 try {
5208 receiver.finished();
5209 } catch (RemoteException ex) {
5210 }
5211 }
5212
5213 return list;
5214 }
5215
5216 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5217 int flags) {
5218 synchronized (this) {
5219 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5220 "getRecentTasks()");
5221
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005222 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005224 final int N = mRecentTasks.size();
5225 ArrayList<ActivityManager.RecentTaskInfo> res
5226 = new ArrayList<ActivityManager.RecentTaskInfo>(
5227 maxNum < N ? maxNum : N);
5228 for (int i=0; i<N && maxNum > 0; i++) {
5229 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackborn905577f2011-09-07 18:31:28 -07005230 // Return the entry if desired by the caller. We always return
5231 // the first entry, because callers always expect this to be the
5232 // forground app. We may filter others if the caller has
5233 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5234 // we should exclude the entry.
5235 if (i == 0
5236 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005237 || (tr.intent == null)
5238 || ((tr.intent.getFlags()
5239 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5240 ActivityManager.RecentTaskInfo rti
5241 = new ActivityManager.RecentTaskInfo();
5242 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005243 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005244 rti.baseIntent = new Intent(
5245 tr.intent != null ? tr.intent : tr.affinityIntent);
5246 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005247 rti.description = tr.lastDescription;
5248
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005249 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5250 // Check whether this activity is currently available.
5251 try {
5252 if (rti.origActivity != null) {
5253 if (pm.getActivityInfo(rti.origActivity, 0) == null) {
5254 continue;
5255 }
5256 } else if (rti.baseIntent != null) {
5257 if (pm.queryIntentActivities(rti.baseIntent,
5258 null, 0) == null) {
5259 continue;
5260 }
5261 }
5262 } catch (RemoteException e) {
5263 // Will never happen.
5264 }
5265 }
5266
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005267 res.add(rti);
5268 maxNum--;
5269 }
5270 }
5271 return res;
5272 }
5273 }
5274
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005275 private TaskRecord taskForIdLocked(int id) {
5276 final int N = mRecentTasks.size();
5277 for (int i=0; i<N; i++) {
5278 TaskRecord tr = mRecentTasks.get(i);
5279 if (tr.taskId == id) {
5280 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005281 }
5282 }
5283 return null;
5284 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005285
5286 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5287 synchronized (this) {
5288 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5289 "getTaskThumbnails()");
5290 TaskRecord tr = taskForIdLocked(id);
5291 if (tr != null) {
5292 return mMainStack.getTaskThumbnailsLocked(tr);
5293 }
5294 }
5295 return null;
5296 }
5297
5298 public boolean removeSubTask(int taskId, int subTaskIndex) {
5299 synchronized (this) {
5300 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5301 "removeSubTask()");
5302 long ident = Binder.clearCallingIdentity();
5303 try {
5304 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex) != null;
5305 } finally {
5306 Binder.restoreCallingIdentity(ident);
5307 }
5308 }
5309 }
5310
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005311 private void cleanUpRemovedTaskLocked(ActivityRecord root, boolean killProcesses) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005312 TaskRecord tr = root.task;
5313 Intent baseIntent = new Intent(
5314 tr.intent != null ? tr.intent : tr.affinityIntent);
5315 ComponentName component = baseIntent.getComponent();
5316 if (component == null) {
5317 Slog.w(TAG, "Now component for base intent of task: " + tr);
5318 return;
5319 }
5320
5321 // Find any running services associated with this app.
5322 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
5323 for (ServiceRecord sr : mServices.values()) {
5324 if (sr.packageName.equals(component.getPackageName())) {
5325 services.add(sr);
5326 }
5327 }
5328
5329 // Take care of any running services associated with the app.
5330 for (int i=0; i<services.size(); i++) {
5331 ServiceRecord sr = services.get(i);
5332 if (sr.startRequested) {
5333 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005334 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005335 stopServiceLocked(sr);
5336 } else {
5337 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
5338 sr.makeNextStartId(), baseIntent, -1));
5339 if (sr.app != null && sr.app.thread != null) {
5340 sendServiceArgsLocked(sr, false);
5341 }
5342 }
5343 }
5344 }
5345
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005346 if (killProcesses) {
5347 // Find any running processes associated with this app.
5348 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
5349 SparseArray<ProcessRecord> appProcs
5350 = mProcessNames.getMap().get(component.getPackageName());
5351 if (appProcs != null) {
5352 for (int i=0; i<appProcs.size(); i++) {
5353 procs.add(appProcs.valueAt(i));
5354 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005355 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005356
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005357 // Kill the running processes.
5358 for (int i=0; i<procs.size(); i++) {
5359 ProcessRecord pr = procs.get(i);
5360 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5361 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5362 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5363 pr.processName, pr.setAdj, "remove task");
5364 Process.killProcessQuiet(pr.pid);
5365 } else {
5366 pr.waitingToKill = "remove task";
5367 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005368 }
5369 }
5370 }
5371
5372 public boolean removeTask(int taskId, int flags) {
5373 synchronized (this) {
5374 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5375 "removeTask()");
5376 long ident = Binder.clearCallingIdentity();
5377 try {
5378 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1);
5379 if (r != null) {
5380 mRecentTasks.remove(r.task);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005381 cleanUpRemovedTaskLocked(r,
5382 (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005383 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005384 } else {
5385 TaskRecord tr = null;
5386 int i=0;
5387 while (i < mRecentTasks.size()) {
5388 TaskRecord t = mRecentTasks.get(i);
5389 if (t.taskId == taskId) {
5390 tr = t;
5391 break;
5392 }
5393 i++;
5394 }
5395 if (tr != null) {
5396 if (tr.numActivities <= 0) {
5397 // Caller is just removing a recent task that is
5398 // not actively running. That is easy!
5399 mRecentTasks.remove(i);
5400 } else {
5401 Slog.w(TAG, "removeTask: task " + taskId
5402 + " does not have activities to remove, "
5403 + " but numActivities=" + tr.numActivities
5404 + ": " + tr);
5405 }
5406 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005407 }
5408 } finally {
5409 Binder.restoreCallingIdentity(ident);
5410 }
5411 }
5412 return false;
5413 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5416 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005417 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005418 TaskRecord jt = startTask;
5419
5420 // First look backwards
5421 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005422 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005423 if (r.task != jt) {
5424 jt = r.task;
5425 if (affinity.equals(jt.affinity)) {
5426 return j;
5427 }
5428 }
5429 }
5430
5431 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005432 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005433 jt = startTask;
5434 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005435 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005436 if (r.task != jt) {
5437 if (affinity.equals(jt.affinity)) {
5438 return j;
5439 }
5440 jt = r.task;
5441 }
5442 }
5443
5444 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005445 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005446 return N-1;
5447 }
5448
5449 return -1;
5450 }
5451
5452 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005453 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005454 */
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005455 public void moveTaskToFront(int task, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5457 "moveTaskToFront()");
5458
5459 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005460 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5461 Binder.getCallingUid(), "Task to front")) {
5462 return;
5463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005464 final long origId = Binder.clearCallingIdentity();
5465 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005466 TaskRecord tr = taskForIdLocked(task);
5467 if (tr != null) {
5468 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5469 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005471 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5472 // Caller wants the home activity moved with it. To accomplish this,
5473 // we'll just move the home task to the top first.
5474 mMainStack.moveHomeToFrontLocked();
5475 }
5476 mMainStack.moveTaskToFrontLocked(tr, null);
5477 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005478 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005479 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5480 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005481 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005482 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5483 mMainStack.mUserLeaving = true;
5484 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005485 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5486 // Caller wants the home activity moved with it. To accomplish this,
5487 // we'll just move the home task to the top first.
5488 mMainStack.moveHomeToFrontLocked();
5489 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005490 mMainStack.moveTaskToFrontLocked(hr.task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005491 return;
5492 }
5493 }
5494 } finally {
5495 Binder.restoreCallingIdentity(origId);
5496 }
5497 }
5498 }
5499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005500 public void moveTaskToBack(int task) {
5501 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5502 "moveTaskToBack()");
5503
5504 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005505 if (mMainStack.mResumedActivity != null
5506 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005507 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5508 Binder.getCallingUid(), "Task to back")) {
5509 return;
5510 }
5511 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005512 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005513 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005514 Binder.restoreCallingIdentity(origId);
5515 }
5516 }
5517
5518 /**
5519 * Moves an activity, and all of the other activities within the same task, to the bottom
5520 * of the history stack. The activity's order within the task is unchanged.
5521 *
5522 * @param token A reference to the activity we wish to move
5523 * @param nonRoot If false then this only works if the activity is the root
5524 * of a task; if true it will work for any activity in a task.
5525 * @return Returns true if the move completed, false if not.
5526 */
5527 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
5528 synchronized(this) {
5529 final long origId = Binder.clearCallingIdentity();
5530 int taskId = getTaskForActivityLocked(token, !nonRoot);
5531 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005532 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005533 }
5534 Binder.restoreCallingIdentity(origId);
5535 }
5536 return false;
5537 }
5538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005539 public void moveTaskBackwards(int task) {
5540 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5541 "moveTaskBackwards()");
5542
5543 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005544 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5545 Binder.getCallingUid(), "Task backwards")) {
5546 return;
5547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005548 final long origId = Binder.clearCallingIdentity();
5549 moveTaskBackwardsLocked(task);
5550 Binder.restoreCallingIdentity(origId);
5551 }
5552 }
5553
5554 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005555 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005556 }
5557
5558 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5559 synchronized(this) {
5560 return getTaskForActivityLocked(token, onlyRoot);
5561 }
5562 }
5563
5564 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005565 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566 TaskRecord lastTask = null;
5567 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005568 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005569 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005570 if (!onlyRoot || lastTask != r.task) {
5571 return r.task.taskId;
5572 }
5573 return -1;
5574 }
5575 lastTask = r.task;
5576 }
5577
5578 return -1;
5579 }
5580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005581 public void finishOtherInstances(IBinder token, ComponentName className) {
5582 synchronized(this) {
5583 final long origId = Binder.clearCallingIdentity();
5584
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005585 int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005586 TaskRecord lastTask = null;
5587 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005588 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005589 if (r.realActivity.equals(className)
Dianne Hackbornbe707852011-11-11 14:32:10 -08005590 && r.appToken != token && lastTask != r.task) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005591 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005592 null, "others")) {
5593 i--;
5594 N--;
5595 }
5596 }
5597 lastTask = r.task;
5598 }
5599
5600 Binder.restoreCallingIdentity(origId);
5601 }
5602 }
5603
5604 // =========================================================
5605 // THUMBNAILS
5606 // =========================================================
5607
5608 public void reportThumbnail(IBinder token,
5609 Bitmap thumbnail, CharSequence description) {
5610 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5611 final long origId = Binder.clearCallingIdentity();
5612 sendPendingThumbnail(null, token, thumbnail, description, true);
5613 Binder.restoreCallingIdentity(origId);
5614 }
5615
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005616 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005617 Bitmap thumbnail, CharSequence description, boolean always) {
5618 TaskRecord task = null;
5619 ArrayList receivers = null;
5620
5621 //System.out.println("Send pending thumbnail: " + r);
5622
5623 synchronized(this) {
5624 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005625 r = mMainStack.isInStackLocked(token);
5626 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005627 return;
5628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005629 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005630 if (thumbnail == null && r.thumbHolder != null) {
5631 thumbnail = r.thumbHolder.lastThumbnail;
5632 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005633 }
5634 if (thumbnail == null && !always) {
5635 // If there is no thumbnail, and this entry is not actually
5636 // going away, then abort for now and pick up the next
5637 // thumbnail we get.
5638 return;
5639 }
5640 task = r.task;
5641
5642 int N = mPendingThumbnails.size();
5643 int i=0;
5644 while (i<N) {
5645 PendingThumbnailsRecord pr =
5646 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
5647 //System.out.println("Looking in " + pr.pendingRecords);
5648 if (pr.pendingRecords.remove(r)) {
5649 if (receivers == null) {
5650 receivers = new ArrayList();
5651 }
5652 receivers.add(pr);
5653 if (pr.pendingRecords.size() == 0) {
5654 pr.finished = true;
5655 mPendingThumbnails.remove(i);
5656 N--;
5657 continue;
5658 }
5659 }
5660 i++;
5661 }
5662 }
5663
5664 if (receivers != null) {
5665 final int N = receivers.size();
5666 for (int i=0; i<N; i++) {
5667 try {
5668 PendingThumbnailsRecord pr =
5669 (PendingThumbnailsRecord)receivers.get(i);
5670 pr.receiver.newThumbnail(
5671 task != null ? task.taskId : -1, thumbnail, description);
5672 if (pr.finished) {
5673 pr.receiver.finished();
5674 }
5675 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005676 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005677 }
5678 }
5679 }
5680 }
5681
5682 // =========================================================
5683 // CONTENT PROVIDERS
5684 // =========================================================
5685
Jeff Brown10e89712011-07-08 18:52:57 -07005686 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
5687 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005688 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005689 providers = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005690 queryContentProviders(app.processName, app.info.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005691 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005692 } catch (RemoteException ex) {
5693 }
5694 if (providers != null) {
5695 final int N = providers.size();
5696 for (int i=0; i<N; i++) {
5697 ProviderInfo cpi =
5698 (ProviderInfo)providers.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005699 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5700 ContentProviderRecord cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005701 if (cpr == null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005702 cpr = new ContentProviderRecord(cpi, app.info, comp);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005703 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005704 }
5705 app.pubProviders.put(cpi.name, cpr);
5706 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07005707 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708 }
5709 }
5710 return providers;
5711 }
5712
5713 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07005714 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005715 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
5716 final int callingUid = (r != null) ? r.info.uid : Binder.getCallingUid();
5717 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005718 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005719 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005720 return null;
5721 }
5722 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005723 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005724 == PackageManager.PERMISSION_GRANTED) {
5725 return null;
5726 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005727
5728 PathPermission[] pps = cpi.pathPermissions;
5729 if (pps != null) {
5730 int i = pps.length;
5731 while (i > 0) {
5732 i--;
5733 PathPermission pp = pps[i];
5734 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005735 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005736 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005737 return null;
5738 }
5739 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005740 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07005741 == PackageManager.PERMISSION_GRANTED) {
5742 return null;
5743 }
5744 }
5745 }
5746
Dianne Hackbornb424b632010-08-18 15:59:05 -07005747 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
5748 if (perms != null) {
5749 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
5750 if (uri.getKey().getAuthority().equals(cpi.authority)) {
5751 return null;
5752 }
5753 }
5754 }
5755
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08005756 String msg;
5757 if (!cpi.exported) {
5758 msg = "Permission Denial: opening provider " + cpi.name
5759 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5760 + ", uid=" + callingUid + ") that is not exported from uid "
5761 + cpi.applicationInfo.uid;
5762 } else {
5763 msg = "Permission Denial: opening provider " + cpi.name
5764 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
5765 + ", uid=" + callingUid + ") requires "
5766 + cpi.readPermission + " or " + cpi.writePermission;
5767 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005768 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005769 return msg;
5770 }
5771
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005772 boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5773 if (r != null) {
5774 Integer cnt = r.conProviders.get(cpr);
5775 if (DEBUG_PROVIDER) Slog.v(TAG,
5776 "Adding provider requested by "
5777 + r.processName + " from process "
5778 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5779 + " cnt=" + (cnt == null ? 1 : cnt));
5780 if (cnt == null) {
5781 cpr.clients.add(r);
5782 r.conProviders.put(cpr, new Integer(1));
5783 return true;
5784 } else {
5785 r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
5786 }
5787 } else {
5788 cpr.externals++;
5789 }
5790 return false;
5791 }
5792
5793 boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
5794 if (r != null) {
5795 Integer cnt = r.conProviders.get(cpr);
5796 if (DEBUG_PROVIDER) Slog.v(TAG,
5797 "Removing provider requested by "
5798 + r.processName + " from process "
5799 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
5800 + " cnt=" + cnt);
5801 if (cnt == null || cnt.intValue() <= 1) {
5802 cpr.clients.remove(r);
5803 r.conProviders.remove(cpr);
5804 return true;
5805 } else {
5806 r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
5807 }
5808 } else {
5809 cpr.externals++;
5810 }
5811 return false;
5812 }
5813
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005814 private final ContentProviderHolder getContentProviderImpl(
5815 IApplicationThread caller, String name) {
5816 ContentProviderRecord cpr;
5817 ProviderInfo cpi = null;
5818
5819 synchronized(this) {
5820 ProcessRecord r = null;
5821 if (caller != null) {
5822 r = getRecordForAppLocked(caller);
5823 if (r == null) {
5824 throw new SecurityException(
5825 "Unable to find app for caller " + caller
5826 + " (pid=" + Binder.getCallingPid()
5827 + ") when getting content provider " + name);
5828 }
5829 }
5830
5831 // First check if this content provider has been published...
Dianne Hackborn860755f2010-06-03 18:47:52 -07005832 cpr = mProvidersByName.get(name);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005833 boolean providerRunning = cpr != null;
5834 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005835 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07005836 String msg;
5837 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5838 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005839 }
5840
5841 if (r != null && cpr.canRunHere(r)) {
5842 // This provider has been published or is in the process
5843 // of being published... but it is also allowed to run
5844 // in the caller's process, so don't make a connection
5845 // and just let the caller instantiate its own instance.
5846 if (cpr.provider != null) {
5847 // don't give caller the provider object, it needs
5848 // to make its own.
5849 cpr = new ContentProviderRecord(cpr);
5850 }
5851 return cpr;
5852 }
5853
5854 final long origId = Binder.clearCallingIdentity();
5855
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005856 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005857 // return it right away.
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005858 final boolean countChanged = incProviderCount(r, cpr);
5859 if (countChanged) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005860 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005861 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07005862 // make sure to count it as being accessed and thus
5863 // back up on the LRU list. This is good because
5864 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005865 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07005866 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07005867 }
5868
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005869 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005870 if (false) {
5871 if (cpr.name.flattenToShortString().equals(
5872 "com.android.providers.calendar/.CalendarProvider2")) {
5873 Slog.v(TAG, "****************** KILLING "
5874 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005875 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005876 }
5877 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005878 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005879 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
5880 // NOTE: there is still a race here where a signal could be
5881 // pending on the process even though we managed to update its
5882 // adj level. Not sure what to do about this, but at least
5883 // the race is now smaller.
5884 if (!success) {
5885 // Uh oh... it looks like the provider's process
5886 // has been killed on us. We need to wait for a new
5887 // process to be started, and make sure its death
5888 // doesn't kill our process.
5889 Slog.i(TAG,
5890 "Existing provider " + cpr.name.flattenToShortString()
5891 + " is crashing; detaching " + r);
5892 boolean lastRef = decProviderCount(r, cpr);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005893 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005894 if (!lastRef) {
5895 // This wasn't the last ref our process had on
5896 // the provider... we have now been killed, bail.
5897 return null;
5898 }
5899 providerRunning = false;
5900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005901 }
5902
5903 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005905
Dianne Hackborn295e3c22011-08-25 13:19:08 -07005906 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005907 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005908 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07005909 resolveContentProvider(name,
5910 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005911 } catch (RemoteException ex) {
5912 }
5913 if (cpi == null) {
5914 return null;
5915 }
5916
Dianne Hackbornb424b632010-08-18 15:59:05 -07005917 String msg;
5918 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
5919 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 }
5921
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07005922 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08005923 && !cpi.processName.equals("system")) {
5924 // If this content provider does not run in the system
5925 // process, and the system is not yet ready to run other
5926 // processes, then fail fast instead of hanging.
5927 throw new IllegalArgumentException(
5928 "Attempt to launch content provider before system ready");
5929 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07005930
5931 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
5932 cpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005933 final boolean firstClass = cpr == null;
5934 if (firstClass) {
5935 try {
5936 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005937 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 getApplicationInfo(
5939 cpi.applicationInfo.packageName,
Dianne Hackborn1655be42009-05-08 14:29:01 -07005940 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005941 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005942 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005943 + cpi.name);
5944 return null;
5945 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07005946 cpr = new ContentProviderRecord(cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 } catch (RemoteException ex) {
5948 // pm is in same process, this will never happen.
5949 }
5950 }
5951
5952 if (r != null && cpr.canRunHere(r)) {
5953 // If this is a multiprocess provider, then just return its
5954 // info and allow the caller to instantiate it. Only do
5955 // this if the provider is the same user as the caller's
5956 // process, or can run as root (so can be in any process).
5957 return cpr;
5958 }
5959
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005960 if (DEBUG_PROVIDER) {
5961 RuntimeException e = new RuntimeException("here");
Joe Onorato8a9b2202010-02-26 18:56:32 -08005962 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.info.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07005963 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 }
5965
5966 // This is single process, and our app is now connecting to it.
5967 // See if we are already in the process of launching this
5968 // provider.
5969 final int N = mLaunchingProviders.size();
5970 int i;
5971 for (i=0; i<N; i++) {
5972 if (mLaunchingProviders.get(i) == cpr) {
5973 break;
5974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 }
5976
5977 // If the provider is not already being launched, then get it
5978 // started.
5979 if (i >= N) {
5980 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08005981
5982 try {
5983 // Content provider is now in use, its package can't be stopped.
5984 try {
5985 AppGlobals.getPackageManager().setPackageStoppedState(
5986 cpr.appInfo.packageName, false);
5987 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08005988 } catch (IllegalArgumentException e) {
5989 Slog.w(TAG, "Failed trying to unstop package "
5990 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08005991 }
5992
5993 ProcessRecord proc = startProcessLocked(cpi.processName,
5994 cpr.appInfo, false, 0, "content provider",
5995 new ComponentName(cpi.applicationInfo.packageName,
5996 cpi.name), false);
5997 if (proc == null) {
5998 Slog.w(TAG, "Unable to launch app "
5999 + cpi.applicationInfo.packageName + "/"
6000 + cpi.applicationInfo.uid + " for provider "
6001 + name + ": process is bad");
6002 return null;
6003 }
6004 cpr.launchingApp = proc;
6005 mLaunchingProviders.add(cpr);
6006 } finally {
6007 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006009 }
6010
6011 // Make sure the provider is published (the same provider class
6012 // may be published under multiple names).
6013 if (firstClass) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006014 mProvidersByClass.put(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006015 }
6016 mProvidersByName.put(name, cpr);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006017 incProviderCount(r, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006018 }
6019 }
6020
6021 // Wait for the provider to be published...
6022 synchronized (cpr) {
6023 while (cpr.provider == null) {
6024 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006025 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 + cpi.applicationInfo.packageName + "/"
6027 + cpi.applicationInfo.uid + " for provider "
6028 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006029 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006030 cpi.applicationInfo.packageName,
6031 cpi.applicationInfo.uid, name);
6032 return null;
6033 }
6034 try {
6035 cpr.wait();
6036 } catch (InterruptedException ex) {
6037 }
6038 }
6039 }
6040 return cpr;
6041 }
6042
6043 public final ContentProviderHolder getContentProvider(
6044 IApplicationThread caller, String name) {
6045 if (caller == null) {
6046 String msg = "null IApplicationThread when getting content provider "
6047 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006048 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006049 throw new SecurityException(msg);
6050 }
6051
6052 return getContentProviderImpl(caller, name);
6053 }
6054
6055 private ContentProviderHolder getContentProviderExternal(String name) {
6056 return getContentProviderImpl(null, name);
6057 }
6058
6059 /**
6060 * Drop a content provider from a ProcessRecord's bookkeeping
6061 * @param cpr
6062 */
6063 public void removeContentProvider(IApplicationThread caller, String name) {
6064 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006065 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 if(cpr == null) {
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006067 // remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006068 if (DEBUG_PROVIDER) Slog.v(TAG, name +
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006069 " provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006070 return;
6071 }
6072 final ProcessRecord r = getRecordForAppLocked(caller);
6073 if (r == null) {
6074 throw new SecurityException(
6075 "Unable to find app for caller " + caller +
6076 " when removing content provider " + name);
6077 }
6078 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006079 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6080 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006081 if (localCpr.proc == r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006082 //should not happen. taken care of as a local provider
Joe Onorato8a9b2202010-02-26 18:56:32 -08006083 Slog.w(TAG, "removeContentProvider called on local provider: "
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006084 + cpr.info.name + " in process " + r.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006085 return;
6086 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006087 if (decProviderCount(r, localCpr)) {
6088 updateOomAdjLocked();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07006089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 }
6092 }
6093
6094 private void removeContentProviderExternal(String name) {
6095 synchronized (this) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07006096 ContentProviderRecord cpr = mProvidersByName.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 if(cpr == null) {
6098 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006099 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006100 return;
6101 }
6102
6103 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006104 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
6105 ContentProviderRecord localCpr = mProvidersByClass.get(comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 localCpr.externals--;
6107 if (localCpr.externals < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006108 Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 }
6110 updateOomAdjLocked();
6111 }
6112 }
6113
6114 public final void publishContentProviders(IApplicationThread caller,
6115 List<ContentProviderHolder> providers) {
6116 if (providers == null) {
6117 return;
6118 }
6119
6120 synchronized(this) {
6121 final ProcessRecord r = getRecordForAppLocked(caller);
6122 if (r == null) {
6123 throw new SecurityException(
6124 "Unable to find app for caller " + caller
6125 + " (pid=" + Binder.getCallingPid()
6126 + ") when publishing content providers");
6127 }
6128
6129 final long origId = Binder.clearCallingIdentity();
6130
6131 final int N = providers.size();
6132 for (int i=0; i<N; i++) {
6133 ContentProviderHolder src = providers.get(i);
6134 if (src == null || src.info == null || src.provider == null) {
6135 continue;
6136 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006137 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006138 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006139 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
6140 mProvidersByClass.put(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006141 String names[] = dst.info.authority.split(";");
6142 for (int j = 0; j < names.length; j++) {
6143 mProvidersByName.put(names[j], dst);
6144 }
6145
6146 int NL = mLaunchingProviders.size();
6147 int j;
6148 for (j=0; j<NL; j++) {
6149 if (mLaunchingProviders.get(j) == dst) {
6150 mLaunchingProviders.remove(j);
6151 j--;
6152 NL--;
6153 }
6154 }
6155 synchronized (dst) {
6156 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006157 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006158 dst.notifyAll();
6159 }
6160 updateOomAdjLocked(r);
6161 }
6162 }
6163
6164 Binder.restoreCallingIdentity(origId);
6165 }
6166 }
6167
6168 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006169 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006170 synchronized (mSelf) {
6171 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6172 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006173 if (providers != null) {
6174 for (int i=providers.size()-1; i>=0; i--) {
6175 ProviderInfo pi = (ProviderInfo)providers.get(i);
6176 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6177 Slog.w(TAG, "Not installing system proc provider " + pi.name
6178 + ": not system .apk");
6179 providers.remove(i);
6180 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006181 }
6182 }
6183 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006184 if (providers != null) {
6185 mSystemThread.installSystemProviders(providers);
6186 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006187
6188 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006189
6190 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006191 }
6192
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006193 /**
6194 * Allows app to retrieve the MIME type of a URI without having permission
6195 * to access its content provider.
6196 *
6197 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6198 *
6199 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6200 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6201 */
6202 public String getProviderMimeType(Uri uri) {
6203 final String name = uri.getAuthority();
6204 final long ident = Binder.clearCallingIdentity();
6205 ContentProviderHolder holder = null;
6206
6207 try {
6208 holder = getContentProviderExternal(name);
6209 if (holder != null) {
6210 return holder.provider.getType(uri);
6211 }
6212 } catch (RemoteException e) {
6213 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6214 return null;
6215 } finally {
6216 if (holder != null) {
6217 removeContentProviderExternal(name);
6218 }
6219 Binder.restoreCallingIdentity(ident);
6220 }
6221
6222 return null;
6223 }
6224
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006225 // =========================================================
6226 // GLOBAL MANAGEMENT
6227 // =========================================================
6228
6229 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
6230 ApplicationInfo info, String customProcess) {
6231 String proc = customProcess != null ? customProcess : info.processName;
6232 BatteryStatsImpl.Uid.Proc ps = null;
6233 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6234 synchronized (stats) {
6235 ps = stats.getProcessStatsLocked(info.uid, proc);
6236 }
6237 return new ProcessRecord(ps, thread, info, proc);
6238 }
6239
6240 final ProcessRecord addAppLocked(ApplicationInfo info) {
6241 ProcessRecord app = getProcessRecordLocked(info.processName, info.uid);
6242
6243 if (app == null) {
6244 app = newProcessRecordLocked(null, info, null);
6245 mProcessNames.put(info.processName, info.uid, app);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006246 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006247 }
6248
Dianne Hackborne7f97212011-02-24 14:40:20 -08006249 // This package really, really can not be stopped.
6250 try {
6251 AppGlobals.getPackageManager().setPackageStoppedState(
6252 info.packageName, false);
6253 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006254 } catch (IllegalArgumentException e) {
6255 Slog.w(TAG, "Failed trying to unstop package "
6256 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006257 }
6258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006259 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6260 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6261 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006262 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006263 }
6264 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6265 mPersistentStartingProcesses.add(app);
6266 startProcessLocked(app, "added application", app.processName);
6267 }
6268
6269 return app;
6270 }
6271
6272 public void unhandledBack() {
6273 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6274 "unhandledBack()");
6275
6276 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006277 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006278 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006279 TAG, "Performing unhandledBack(): stack size = " + count);
6280 if (count > 1) {
6281 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006282 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6284 Binder.restoreCallingIdentity(origId);
6285 }
6286 }
6287 }
6288
6289 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
6290 String name = uri.getAuthority();
6291 ContentProviderHolder cph = getContentProviderExternal(name);
6292 ParcelFileDescriptor pfd = null;
6293 if (cph != null) {
6294 // We record the binder invoker's uid in thread-local storage before
6295 // going to the content provider to open the file. Later, in the code
6296 // that handles all permissions checks, we look for this uid and use
6297 // that rather than the Activity Manager's own uid. The effect is that
6298 // we do the check against the caller's permissions even though it looks
6299 // to the content provider like the Activity Manager itself is making
6300 // the request.
6301 sCallerIdentity.set(new Identity(
6302 Binder.getCallingPid(), Binder.getCallingUid()));
6303 try {
6304 pfd = cph.provider.openFile(uri, "r");
6305 } catch (FileNotFoundException e) {
6306 // do nothing; pfd will be returned null
6307 } finally {
6308 // Ensure that whatever happens, we clean up the identity state
6309 sCallerIdentity.remove();
6310 }
6311
6312 // We've got the fd now, so we're done with the provider.
6313 removeContentProviderExternal(name);
6314 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006315 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006316 }
6317 return pfd;
6318 }
6319
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006320 // Actually is sleeping or shutting down or whatever else in the future
6321 // is an inactive state.
6322 public boolean isSleeping() {
6323 return mSleeping || mShuttingDown;
6324 }
6325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006326 public void goingToSleep() {
6327 synchronized(this) {
6328 mSleeping = true;
6329 mWindowManager.setEventDispatching(false);
6330
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006331 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006332
6333 // Initialize the wake times of all processes.
Dianne Hackborn287952c2010-09-22 22:34:31 -07006334 checkExcessivePowerUsageLocked(false);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006335 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6336 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07006337 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006338 }
6339 }
6340
Dianne Hackborn55280a92009-05-07 15:53:46 -07006341 public boolean shutdown(int timeout) {
6342 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6343 != PackageManager.PERMISSION_GRANTED) {
6344 throw new SecurityException("Requires permission "
6345 + android.Manifest.permission.SHUTDOWN);
6346 }
6347
6348 boolean timedout = false;
6349
6350 synchronized(this) {
6351 mShuttingDown = true;
6352 mWindowManager.setEventDispatching(false);
6353
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006354 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006355 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006356 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006357 while (mMainStack.mResumedActivity != null
6358 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006359 long delay = endTime - System.currentTimeMillis();
6360 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006361 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006362 timedout = true;
6363 break;
6364 }
6365 try {
6366 this.wait();
6367 } catch (InterruptedException e) {
6368 }
6369 }
6370 }
6371 }
6372
6373 mUsageStatsService.shutdown();
6374 mBatteryStatsService.shutdown();
6375
6376 return timedout;
6377 }
6378
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006379 public final void activitySlept(IBinder token) {
6380 if (localLOGV) Slog.v(
6381 TAG, "Activity slept: token=" + token);
6382
6383 ActivityRecord r = null;
6384
6385 final long origId = Binder.clearCallingIdentity();
6386
6387 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006388 r = mMainStack.isInStackLocked(token);
6389 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006390 mMainStack.activitySleptLocked(r);
6391 }
6392 }
6393
6394 Binder.restoreCallingIdentity(origId);
6395 }
6396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006397 public void wakingUp() {
6398 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006399 mWindowManager.setEventDispatching(true);
6400 mSleeping = false;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006401 mMainStack.awakeFromSleepingLocked();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006402 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006403 }
6404 }
6405
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006406 public void stopAppSwitches() {
6407 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6408 != PackageManager.PERMISSION_GRANTED) {
6409 throw new SecurityException("Requires permission "
6410 + android.Manifest.permission.STOP_APP_SWITCHES);
6411 }
6412
6413 synchronized(this) {
6414 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
6415 + APP_SWITCH_DELAY_TIME;
6416 mDidAppSwitch = false;
6417 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6418 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
6419 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
6420 }
6421 }
6422
6423 public void resumeAppSwitches() {
6424 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
6425 != PackageManager.PERMISSION_GRANTED) {
6426 throw new SecurityException("Requires permission "
6427 + android.Manifest.permission.STOP_APP_SWITCHES);
6428 }
6429
6430 synchronized(this) {
6431 // Note that we don't execute any pending app switches... we will
6432 // let those wait until either the timeout, or the next start
6433 // activity request.
6434 mAppSwitchesAllowedTime = 0;
6435 }
6436 }
6437
6438 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
6439 String name) {
6440 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
6441 return true;
6442 }
6443
6444 final int perm = checkComponentPermission(
6445 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006446 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006447 if (perm == PackageManager.PERMISSION_GRANTED) {
6448 return true;
6449 }
6450
Joe Onorato8a9b2202010-02-26 18:56:32 -08006451 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006452 return false;
6453 }
6454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006455 public void setDebugApp(String packageName, boolean waitForDebugger,
6456 boolean persistent) {
6457 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
6458 "setDebugApp()");
6459
6460 // Note that this is not really thread safe if there are multiple
6461 // callers into it at the same time, but that's not a situation we
6462 // care about.
6463 if (persistent) {
6464 final ContentResolver resolver = mContext.getContentResolver();
6465 Settings.System.putString(
6466 resolver, Settings.System.DEBUG_APP,
6467 packageName);
6468 Settings.System.putInt(
6469 resolver, Settings.System.WAIT_FOR_DEBUGGER,
6470 waitForDebugger ? 1 : 0);
6471 }
6472
6473 synchronized (this) {
6474 if (!persistent) {
6475 mOrigDebugApp = mDebugApp;
6476 mOrigWaitForDebugger = mWaitForDebugger;
6477 }
6478 mDebugApp = packageName;
6479 mWaitForDebugger = waitForDebugger;
6480 mDebugTransient = !persistent;
6481 if (packageName != null) {
6482 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -07006483 forceStopPackageLocked(packageName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 Binder.restoreCallingIdentity(origId);
6485 }
6486 }
6487 }
6488
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07006489 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
6490 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
6491 synchronized (this) {
6492 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
6493 if (!isDebuggable) {
6494 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
6495 throw new SecurityException("Process not debuggable: " + app.packageName);
6496 }
6497 }
6498 mProfileApp = processName;
6499 mProfileFile = profileFile;
6500 if (mProfileFd != null) {
6501 try {
6502 mProfileFd.close();
6503 } catch (IOException e) {
6504 }
6505 mProfileFd = null;
6506 }
6507 mProfileFd = profileFd;
6508 mProfileType = 0;
6509 mAutoStopProfiler = autoStopProfiler;
6510 }
6511 }
6512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 public void setAlwaysFinish(boolean enabled) {
6514 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
6515 "setAlwaysFinish()");
6516
6517 Settings.System.putInt(
6518 mContext.getContentResolver(),
6519 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
6520
6521 synchronized (this) {
6522 mAlwaysFinishActivities = enabled;
6523 }
6524 }
6525
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006526 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006527 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006528 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006529 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006530 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006531 }
6532 }
6533
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08006534 public boolean isUserAMonkey() {
6535 // For now the fact that there is a controller implies
6536 // we have a monkey.
6537 synchronized (this) {
6538 return mController != null;
6539 }
6540 }
6541
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006542 public void registerActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006543 synchronized (this) {
6544 mWatchers.register(watcher);
6545 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006546 }
6547
6548 public void unregisterActivityWatcher(IActivityWatcher watcher) {
Josh Bartel2ecce342010-02-25 10:55:48 -06006549 synchronized (this) {
6550 mWatchers.unregister(watcher);
6551 }
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006552 }
6553
Jeff Sharkeya4620792011-05-20 15:29:23 -07006554 public void registerProcessObserver(IProcessObserver observer) {
6555 mProcessObservers.register(observer);
6556 }
6557
6558 public void unregisterProcessObserver(IProcessObserver observer) {
6559 mProcessObservers.unregister(observer);
6560 }
6561
Daniel Sandler69a48172010-06-23 16:29:36 -04006562 public void setImmersive(IBinder token, boolean immersive) {
6563 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006564 ActivityRecord r = mMainStack.isInStackLocked(token);
6565 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006566 throw new IllegalArgumentException();
6567 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006568 r.immersive = immersive;
6569 }
6570 }
6571
6572 public boolean isImmersive(IBinder token) {
6573 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006574 ActivityRecord r = mMainStack.isInStackLocked(token);
6575 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04006576 throw new IllegalArgumentException();
6577 }
Daniel Sandler69a48172010-06-23 16:29:36 -04006578 return r.immersive;
6579 }
6580 }
6581
6582 public boolean isTopActivityImmersive() {
6583 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006584 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04006585 return (r != null) ? r.immersive : false;
6586 }
6587 }
6588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006589 public final void enterSafeMode() {
6590 synchronized(this) {
6591 // It only makes sense to do this before the system is ready
6592 // and started launching other packages.
6593 if (!mSystemReady) {
6594 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006595 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006596 } catch (RemoteException e) {
6597 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006598 }
6599 }
6600 }
6601
Jeff Brownb09abc12011-01-13 21:08:27 -08006602 public final void showSafeModeOverlay() {
6603 View v = LayoutInflater.from(mContext).inflate(
6604 com.android.internal.R.layout.safe_mode, null);
6605 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
6606 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
6607 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
6608 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
6609 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
6610 lp.format = v.getBackground().getOpacity();
6611 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
6612 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
6613 ((WindowManager)mContext.getSystemService(
6614 Context.WINDOW_SERVICE)).addView(v, lp);
6615 }
6616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006617 public void noteWakeupAlarm(IIntentSender sender) {
6618 if (!(sender instanceof PendingIntentRecord)) {
6619 return;
6620 }
6621 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
6622 synchronized (stats) {
6623 if (mBatteryStatsService.isOnBattery()) {
6624 mBatteryStatsService.enforceCallingPermission();
6625 PendingIntentRecord rec = (PendingIntentRecord)sender;
6626 int MY_UID = Binder.getCallingUid();
6627 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
6628 BatteryStatsImpl.Uid.Pkg pkg =
6629 stats.getPackageStatsLocked(uid, rec.key.packageName);
6630 pkg.incWakeupsLocked();
6631 }
6632 }
6633 }
6634
Dianne Hackborn64825172011-03-02 21:32:58 -08006635 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006636 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006637 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006638 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006639 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006640 // XXX Note: don't acquire main activity lock here, because the window
6641 // manager calls in with its locks held.
6642
6643 boolean killed = false;
6644 synchronized (mPidsSelfLocked) {
6645 int[] types = new int[pids.length];
6646 int worstType = 0;
6647 for (int i=0; i<pids.length; i++) {
6648 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6649 if (proc != null) {
6650 int type = proc.setAdj;
6651 types[i] = type;
6652 if (type > worstType) {
6653 worstType = type;
6654 }
6655 }
6656 }
6657
Dianne Hackborn64825172011-03-02 21:32:58 -08006658 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006659 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006660 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
6661 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07006662 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 }
Dianne Hackborn64825172011-03-02 21:32:58 -08006664
6665 // If this is not a secure call, don't let it kill processes that
6666 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006667 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
6668 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08006669 }
6670
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006671 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006672 for (int i=0; i<pids.length; i++) {
6673 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
6674 if (proc == null) {
6675 continue;
6676 }
6677 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006678 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07006679 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07006680 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
6681 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006682 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07006683 proc.killedBackground = true;
6684 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006685 }
6686 }
6687 }
6688 return killed;
6689 }
6690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006691 public final void startRunning(String pkg, String cls, String action,
6692 String data) {
6693 synchronized(this) {
6694 if (mStartRunning) {
6695 return;
6696 }
6697 mStartRunning = true;
6698 mTopComponent = pkg != null && cls != null
6699 ? new ComponentName(pkg, cls) : null;
6700 mTopAction = action != null ? action : Intent.ACTION_MAIN;
6701 mTopData = data;
6702 if (!mSystemReady) {
6703 return;
6704 }
6705 }
6706
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006707 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006708 }
6709
6710 private void retrieveSettings() {
6711 final ContentResolver resolver = mContext.getContentResolver();
6712 String debugApp = Settings.System.getString(
6713 resolver, Settings.System.DEBUG_APP);
6714 boolean waitForDebugger = Settings.System.getInt(
6715 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
6716 boolean alwaysFinishActivities = Settings.System.getInt(
6717 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
6718
6719 Configuration configuration = new Configuration();
6720 Settings.System.getConfiguration(resolver, configuration);
6721
6722 synchronized (this) {
6723 mDebugApp = mOrigDebugApp = debugApp;
6724 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
6725 mAlwaysFinishActivities = alwaysFinishActivities;
6726 // This happens before any activities are started, so we can
6727 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08006728 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006729 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006730 }
6731 }
6732
6733 public boolean testIsSystemReady() {
6734 // no need to synchronize(this) just to read & return the value
6735 return mSystemReady;
6736 }
6737
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006738 private static File getCalledPreBootReceiversFile() {
6739 File dataDir = Environment.getDataDirectory();
6740 File systemDir = new File(dataDir, "system");
6741 File fname = new File(systemDir, "called_pre_boots.dat");
6742 return fname;
6743 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07006744
6745 static final int LAST_DONE_VERSION = 10000;
6746
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006747 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
6748 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
6749 File file = getCalledPreBootReceiversFile();
6750 FileInputStream fis = null;
6751 try {
6752 fis = new FileInputStream(file);
6753 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006754 int fvers = dis.readInt();
6755 if (fvers == LAST_DONE_VERSION) {
6756 String vers = dis.readUTF();
6757 String codename = dis.readUTF();
6758 String build = dis.readUTF();
6759 if (android.os.Build.VERSION.RELEASE.equals(vers)
6760 && android.os.Build.VERSION.CODENAME.equals(codename)
6761 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
6762 int num = dis.readInt();
6763 while (num > 0) {
6764 num--;
6765 String pkg = dis.readUTF();
6766 String cls = dis.readUTF();
6767 lastDoneReceivers.add(new ComponentName(pkg, cls));
6768 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006769 }
6770 }
6771 } catch (FileNotFoundException e) {
6772 } catch (IOException e) {
6773 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
6774 } finally {
6775 if (fis != null) {
6776 try {
6777 fis.close();
6778 } catch (IOException e) {
6779 }
6780 }
6781 }
6782 return lastDoneReceivers;
6783 }
6784
6785 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
6786 File file = getCalledPreBootReceiversFile();
6787 FileOutputStream fos = null;
6788 DataOutputStream dos = null;
6789 try {
6790 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
6791 fos = new FileOutputStream(file);
6792 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07006793 dos.writeInt(LAST_DONE_VERSION);
6794 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006795 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006796 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006797 dos.writeInt(list.size());
6798 for (int i=0; i<list.size(); i++) {
6799 dos.writeUTF(list.get(i).getPackageName());
6800 dos.writeUTF(list.get(i).getClassName());
6801 }
6802 } catch (IOException e) {
6803 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
6804 file.delete();
6805 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07006806 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006807 if (dos != null) {
6808 try {
6809 dos.close();
6810 } catch (IOException e) {
6811 // TODO Auto-generated catch block
6812 e.printStackTrace();
6813 }
6814 }
6815 }
6816 }
6817
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006818 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006819 synchronized(this) {
6820 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006821 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 return;
6823 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006824
6825 // Check to see if there are any update receivers to run.
6826 if (!mDidUpdate) {
6827 if (mWaitingUpdate) {
6828 return;
6829 }
6830 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
6831 List<ResolveInfo> ris = null;
6832 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006833 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006834 intent, null, 0);
6835 } catch (RemoteException e) {
6836 }
6837 if (ris != null) {
6838 for (int i=ris.size()-1; i>=0; i--) {
6839 if ((ris.get(i).activityInfo.applicationInfo.flags
6840 &ApplicationInfo.FLAG_SYSTEM) == 0) {
6841 ris.remove(i);
6842 }
6843 }
6844 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006845
6846 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
6847
6848 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006849 for (int i=0; i<ris.size(); i++) {
6850 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006851 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6852 if (lastDoneReceivers.contains(comp)) {
6853 ris.remove(i);
6854 i--;
6855 }
6856 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07006857
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006858 for (int i=0; i<ris.size(); i++) {
6859 ActivityInfo ai = ris.get(i).activityInfo;
6860 ComponentName comp = new ComponentName(ai.packageName, ai.name);
6861 doneReceivers.add(comp);
6862 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006863 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08006864 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006865 finisher = new IIntentReceiver.Stub() {
6866 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07006867 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006868 boolean sticky) {
6869 // The raw IIntentReceiver interface is called
6870 // with the AM lock held, so redispatch to
6871 // execute our code without the lock.
6872 mHandler.post(new Runnable() {
6873 public void run() {
6874 synchronized (ActivityManagerService.this) {
6875 mDidUpdate = true;
6876 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006877 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07006878 showBootMessage(mContext.getText(
6879 R.string.android_upgrading_complete),
6880 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07006881 systemReady(goingCallback);
6882 }
6883 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006884 }
6885 };
6886 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006887 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006888 broadcastIntentLocked(null, null, intent, null, finisher,
6889 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackbornd6847842010-01-12 18:14:19 -08006890 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006891 mWaitingUpdate = true;
6892 }
6893 }
6894 }
6895 if (mWaitingUpdate) {
6896 return;
6897 }
6898 mDidUpdate = true;
6899 }
6900
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006901 mSystemReady = true;
6902 if (!mStartRunning) {
6903 return;
6904 }
6905 }
6906
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006907 ArrayList<ProcessRecord> procsToKill = null;
6908 synchronized(mPidsSelfLocked) {
6909 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
6910 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
6911 if (!isAllowedWhileBooting(proc.info)){
6912 if (procsToKill == null) {
6913 procsToKill = new ArrayList<ProcessRecord>();
6914 }
6915 procsToKill.add(proc);
6916 }
6917 }
6918 }
6919
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006920 synchronized(this) {
6921 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006922 for (int i=procsToKill.size()-1; i>=0; i--) {
6923 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08006924 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08006925 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006926 }
6927 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07006928
6929 // Now that we have cleaned up any update processes, we
6930 // are ready to start launching real processes and know that
6931 // we won't trample on them any more.
6932 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006933 }
6934
Joe Onorato8a9b2202010-02-26 18:56:32 -08006935 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006936 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006937 SystemClock.uptimeMillis());
6938
6939 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07006940 // Make sure we have no pre-ready processes sitting around.
6941
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006942 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
6943 ResolveInfo ri = mContext.getPackageManager()
6944 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07006945 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006946 CharSequence errorMsg = null;
6947 if (ri != null) {
6948 ActivityInfo ai = ri.activityInfo;
6949 ApplicationInfo app = ai.applicationInfo;
6950 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
6951 mTopAction = Intent.ACTION_FACTORY_TEST;
6952 mTopData = null;
6953 mTopComponent = new ComponentName(app.packageName,
6954 ai.name);
6955 } else {
6956 errorMsg = mContext.getResources().getText(
6957 com.android.internal.R.string.factorytest_not_system);
6958 }
6959 } else {
6960 errorMsg = mContext.getResources().getText(
6961 com.android.internal.R.string.factorytest_no_action);
6962 }
6963 if (errorMsg != null) {
6964 mTopAction = null;
6965 mTopData = null;
6966 mTopComponent = null;
6967 Message msg = Message.obtain();
6968 msg.what = SHOW_FACTORY_ERROR_MSG;
6969 msg.getData().putCharSequence("msg", errorMsg);
6970 mHandler.sendMessage(msg);
6971 }
6972 }
6973 }
6974
6975 retrieveSettings();
6976
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07006977 if (goingCallback != null) goingCallback.run();
6978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006979 synchronized (this) {
6980 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
6981 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006982 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006983 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006984 if (apps != null) {
6985 int N = apps.size();
6986 int i;
6987 for (i=0; i<N; i++) {
6988 ApplicationInfo info
6989 = (ApplicationInfo)apps.get(i);
6990 if (info != null &&
6991 !info.packageName.equals("android")) {
6992 addAppLocked(info);
6993 }
6994 }
6995 }
6996 } catch (RemoteException ex) {
6997 // pm is in same process, this will never happen.
6998 }
6999 }
7000
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007001 // Start up initial activity.
7002 mBooting = true;
7003
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007004 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007005 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007006 Message msg = Message.obtain();
7007 msg.what = SHOW_UID_ERROR_MSG;
7008 mHandler.sendMessage(msg);
7009 }
7010 } catch (RemoteException e) {
7011 }
7012
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007013 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007014 }
7015 }
7016
Dan Egnorb7f03672009-12-09 16:22:32 -08007017 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007018 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007019 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007020 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007021 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007022 startAppProblemLocked(app);
7023 app.stopFreezingAllLocked();
7024 return handleAppCrashLocked(app);
7025 }
7026
Dan Egnorb7f03672009-12-09 16:22:32 -08007027 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007028 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007029 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007030 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007031 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7032 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007033 startAppProblemLocked(app);
7034 app.stopFreezingAllLocked();
7035 }
7036
7037 /**
7038 * Generate a process error record, suitable for attachment to a ProcessRecord.
7039 *
7040 * @param app The ProcessRecord in which the error occurred.
7041 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7042 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007043 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007044 * @param shortMsg Short message describing the crash.
7045 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007046 * @param stackTrace Full crash stack trace, may be null.
7047 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007048 * @return Returns a fully-formed AppErrorStateInfo record.
7049 */
7050 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007051 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007052 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007054 report.condition = condition;
7055 report.processName = app.processName;
7056 report.pid = app.pid;
7057 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007058 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007059 report.shortMsg = shortMsg;
7060 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007061 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007062
7063 return report;
7064 }
7065
Dan Egnor42471dd2010-01-07 17:25:22 -08007066 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007067 synchronized (this) {
7068 app.crashing = false;
7069 app.crashingReport = null;
7070 app.notResponding = false;
7071 app.notRespondingReport = null;
7072 if (app.anrDialog == fromDialog) {
7073 app.anrDialog = null;
7074 }
7075 if (app.waitDialog == fromDialog) {
7076 app.waitDialog = null;
7077 }
7078 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007079 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007080 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007081 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7082 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007083 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007085 }
7086 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007087
Dan Egnorb7f03672009-12-09 16:22:32 -08007088 private boolean handleAppCrashLocked(ProcessRecord app) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007089 long now = SystemClock.uptimeMillis();
7090
7091 Long crashTime = mProcessCrashTimes.get(app.info.processName,
7092 app.info.uid);
Dianne Hackborn7d608422011-08-07 16:24:18 -07007093 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007094 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007095 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007096 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007097 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007098 app.info.processName, app.info.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007099 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7100 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007101 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007102 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007103 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007104 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007105 }
7106 }
7107 if (!app.persistent) {
7108 // We don't want to start this process again until the user
7109 // explicitly does so... but for persistent process, we really
7110 // need to keep it running. If a persistent process is actually
7111 // repeatedly crashing, then badness for everyone.
Doug Zongker2bec3d42009-12-04 12:52:44 -08007112 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.info.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007113 app.info.processName);
7114 mBadProcesses.put(app.info.processName, app.info.uid, now);
7115 app.bad = true;
7116 mProcessCrashTimes.remove(app.info.processName, app.info.uid);
7117 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007118 // Don't let services in this process be restarted and potentially
7119 // annoy the user repeatedly. Unless it is persistent, since those
7120 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007121 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007122 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007123 return false;
7124 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007125 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007126 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007127 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007128 if (r.app == app) {
7129 // If the top running activity is from this crashing
7130 // process, then terminate it to avoid getting in a loop.
7131 Slog.w(TAG, " Force finishing activity "
7132 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007133 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007134 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007135 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007136 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007137 // stopped, to avoid a situation where one will get
7138 // re-start our crashing activity once it gets resumed again.
7139 index--;
7140 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007141 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007142 if (r.state == ActivityState.RESUMED
7143 || r.state == ActivityState.PAUSING
7144 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007145 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007146 Slog.w(TAG, " Force finishing activity "
7147 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007148 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007149 Activity.RESULT_CANCELED, null, "crashed");
7150 }
7151 }
7152 }
7153 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007154 }
7155
7156 // Bump up the crash count of any services currently running in the proc.
7157 if (app.services.size() != 0) {
7158 // Any services running in the application need to be placed
7159 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007160 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007161 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007162 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007163 sr.crashCount++;
7164 }
7165 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007166
7167 // If the crashing process is what we consider to be the "home process" and it has been
7168 // replaced by a third-party app, clear the package preferred activities from packages
7169 // with a home activity running in the process to prevent a repeatedly crashing app
7170 // from blocking the user to manually clear the list.
7171 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7172 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7173 Iterator it = mHomeProcess.activities.iterator();
7174 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007175 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007176 if (r.isHomeActivity) {
7177 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7178 try {
7179 ActivityThread.getPackageManager()
7180 .clearPackagePreferredActivities(r.packageName);
7181 } catch (RemoteException c) {
7182 // pm is in same process, this will never happen.
7183 }
7184 }
7185 }
7186 }
7187
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007188 mProcessCrashTimes.put(app.info.processName, app.info.uid, now);
7189 return true;
7190 }
7191
7192 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007193 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7194 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007195 skipCurrentReceiverLocked(app);
7196 }
7197
7198 void skipCurrentReceiverLocked(ProcessRecord app) {
7199 boolean reschedule = false;
7200 BroadcastRecord r = app.curReceiver;
7201 if (r != null) {
7202 // The current broadcast is waiting for this app's receiver
7203 // to be finished. Looks like that's not going to happen, so
7204 // let the broadcast continue.
Jeff Brown4d94a762010-09-23 11:33:28 -07007205 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007206 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7207 r.resultExtras, r.resultAbort, true);
7208 reschedule = true;
7209 }
7210 r = mPendingBroadcast;
7211 if (r != null && r.curApp == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007212 if (DEBUG_BROADCAST) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007213 "skip & discard pending app " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -07007214 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007215 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
7216 r.resultExtras, r.resultAbort, true);
7217 reschedule = true;
7218 }
7219 if (reschedule) {
7220 scheduleBroadcastsLocked();
7221 }
7222 }
7223
Dan Egnor60d87622009-12-16 16:32:58 -08007224 /**
7225 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7226 * The application process will exit immediately after this call returns.
7227 * @param app object of the crashing app, null for the system server
7228 * @param crashInfo describing the exception
7229 */
7230 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007231 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007232 final String processName = app == null ? "system_server"
7233 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007234
7235 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007236 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007237 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007238 crashInfo.exceptionClassName,
7239 crashInfo.exceptionMessage,
7240 crashInfo.throwFileName,
7241 crashInfo.throwLineNumber);
7242
Jeff Sharkeya353d262011-10-28 11:12:06 -07007243 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007244
7245 crashApplication(r, crashInfo);
7246 }
7247
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007248 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007249 IBinder app,
7250 int violationMask,
7251 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007252 ProcessRecord r = findAppProcess(app, "StrictMode");
7253 if (r == null) {
7254 return;
7255 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007256
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007257 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007258 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007259 boolean logIt = true;
7260 synchronized (mAlreadyLoggedViolatedStacks) {
7261 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7262 logIt = false;
7263 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007264 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007265 // the relative pain numbers, without logging all
7266 // the stack traces repeatedly. We'd want to do
7267 // likewise in the client code, which also does
7268 // dup suppression, before the Binder call.
7269 } else {
7270 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7271 mAlreadyLoggedViolatedStacks.clear();
7272 }
7273 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7274 }
7275 }
7276 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007277 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007278 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007279 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007280
7281 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7282 AppErrorResult result = new AppErrorResult();
7283 synchronized (this) {
7284 final long origId = Binder.clearCallingIdentity();
7285
7286 Message msg = Message.obtain();
7287 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7288 HashMap<String, Object> data = new HashMap<String, Object>();
7289 data.put("result", result);
7290 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007291 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007292 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007293 msg.obj = data;
7294 mHandler.sendMessage(msg);
7295
7296 Binder.restoreCallingIdentity(origId);
7297 }
7298 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007299 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007300 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007301 }
7302
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007303 // Depending on the policy in effect, there could be a bunch of
7304 // these in quick succession so we try to batch these together to
7305 // minimize disk writes, number of dropbox entries, and maximize
7306 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007307 private void logStrictModeViolationToDropBox(
7308 ProcessRecord process,
7309 StrictMode.ViolationInfo info) {
7310 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007311 return;
7312 }
7313 final boolean isSystemApp = process == null ||
7314 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7315 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007316 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007317 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7318 final DropBoxManager dbox = (DropBoxManager)
7319 mContext.getSystemService(Context.DROPBOX_SERVICE);
7320
7321 // Exit early if the dropbox isn't configured to accept this report type.
7322 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7323
7324 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007325 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007326 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7327 synchronized (sb) {
7328 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007329 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007330 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7331 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007332 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7333 if (info.violationNumThisLoop != 0) {
7334 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7335 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007336 if (info.numAnimationsRunning != 0) {
7337 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7338 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007339 if (info.broadcastIntentAction != null) {
7340 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7341 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007342 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007343 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007344 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007345 if (info.numInstances != -1) {
7346 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7347 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007348 if (info.tags != null) {
7349 for (String tag : info.tags) {
7350 sb.append("Span-Tag: ").append(tag).append("\n");
7351 }
7352 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007353 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007354 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
7355 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007356 }
7357 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007358
7359 // Only buffer up to ~64k. Various logging bits truncate
7360 // things at 128k.
7361 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007362 }
7363
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007364 // Flush immediately if the buffer's grown too large, or this
7365 // is a non-system app. Non-system apps are isolated with a
7366 // different tag & policy and not batched.
7367 //
7368 // Batching is useful during internal testing with
7369 // StrictMode settings turned up high. Without batching,
7370 // thousands of separate files could be created on boot.
7371 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007372 new Thread("Error dump: " + dropboxTag) {
7373 @Override
7374 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007375 String report;
7376 synchronized (sb) {
7377 report = sb.toString();
7378 sb.delete(0, sb.length());
7379 sb.trimToSize();
7380 }
7381 if (report.length() != 0) {
7382 dbox.addText(dropboxTag, report);
7383 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007384 }
7385 }.start();
7386 return;
7387 }
7388
7389 // System app batching:
7390 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007391 // An existing dropbox-writing thread is outstanding, so
7392 // we don't need to start it up. The existing thread will
7393 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007394 return;
7395 }
7396
7397 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
7398 // (After this point, we shouldn't access AMS internal data structures.)
7399 new Thread("Error dump: " + dropboxTag) {
7400 @Override
7401 public void run() {
7402 // 5 second sleep to let stacks arrive and be batched together
7403 try {
7404 Thread.sleep(5000); // 5 seconds
7405 } catch (InterruptedException e) {}
7406
7407 String errorReport;
7408 synchronized (mStrictModeBuffer) {
7409 errorReport = mStrictModeBuffer.toString();
7410 if (errorReport.length() == 0) {
7411 return;
7412 }
7413 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
7414 mStrictModeBuffer.trimToSize();
7415 }
7416 dbox.addText(dropboxTag, errorReport);
7417 }
7418 }.start();
7419 }
7420
Dan Egnor60d87622009-12-16 16:32:58 -08007421 /**
7422 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
7423 * @param app object of the crashing app, null for the system server
7424 * @param tag reported by the caller
7425 * @param crashInfo describing the context of the error
7426 * @return true if the process should exit immediately (WTF is fatal)
7427 */
7428 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08007429 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007430 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007431 final String processName = app == null ? "system_server"
7432 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007433
7434 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007435 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007436 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007437 tag, crashInfo.exceptionMessage);
7438
Jeff Sharkeya353d262011-10-28 11:12:06 -07007439 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007440
Dianne Hackborn1ab43772011-03-15 14:38:02 -07007441 if (r != null && r.pid != Process.myPid() &&
7442 Settings.Secure.getInt(mContext.getContentResolver(),
7443 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08007444 crashApplication(r, crashInfo);
7445 return true;
7446 } else {
7447 return false;
7448 }
7449 }
7450
7451 /**
7452 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
7453 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
7454 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08007455 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08007456 if (app == null) {
7457 return null;
7458 }
7459
7460 synchronized (this) {
7461 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
7462 final int NA = apps.size();
7463 for (int ia=0; ia<NA; ia++) {
7464 ProcessRecord p = apps.valueAt(ia);
7465 if (p.thread != null && p.thread.asBinder() == app) {
7466 return p;
7467 }
7468 }
7469 }
7470
Dianne Hackborncb44d962011-03-10 17:02:27 -08007471 Slog.w(TAG, "Can't find mystery application for " + reason
7472 + " from pid=" + Binder.getCallingPid()
7473 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08007474 return null;
7475 }
7476 }
7477
7478 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007479 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
7480 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08007481 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07007482 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
7483 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007484 // Watchdog thread ends up invoking this function (with
7485 // a null ProcessRecord) to add the stack file to dropbox.
7486 // Do not acquire a lock on this (am) in such cases, as it
7487 // could cause a potential deadlock, if and when watchdog
7488 // is invoked due to unavailability of lock on am and it
7489 // would prevent watchdog from killing system_server.
7490 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007491 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08007492 return;
7493 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07007494 // Note: ProcessRecord 'process' is guarded by the service
7495 // instance. (notably process.pkgList, which could otherwise change
7496 // concurrently during execution of this method)
7497 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07007498 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08007499 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007500 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08007501 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
7502 for (String pkg : process.pkgList) {
7503 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08007504 try {
Dan Egnora455d192010-03-12 08:52:28 -08007505 PackageInfo pi = pm.getPackageInfo(pkg, 0);
7506 if (pi != null) {
7507 sb.append(" v").append(pi.versionCode);
7508 if (pi.versionName != null) {
7509 sb.append(" (").append(pi.versionName).append(")");
7510 }
7511 }
7512 } catch (RemoteException e) {
7513 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08007514 }
Dan Egnora455d192010-03-12 08:52:28 -08007515 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08007516 }
Dan Egnora455d192010-03-12 08:52:28 -08007517 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007518 }
7519
7520 private static String processClass(ProcessRecord process) {
7521 if (process == null || process.pid == MY_PID) {
7522 return "system_server";
7523 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
7524 return "system_app";
7525 } else {
7526 return "data_app";
7527 }
7528 }
7529
7530 /**
7531 * Write a description of an error (crash, WTF, ANR) to the drop box.
7532 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
7533 * @param process which caused the error, null means the system server
7534 * @param activity which triggered the error, null if unknown
7535 * @param parent activity related to the error, null if unknown
7536 * @param subject line related to the error, null if absent
7537 * @param report in long form describing the error, null if absent
7538 * @param logFile to include in the report, null if none
7539 * @param crashInfo giving an application stack trace, null if absent
7540 */
7541 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07007542 ProcessRecord process, String processName, ActivityRecord activity,
7543 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007544 final String report, final File logFile,
7545 final ApplicationErrorReport.CrashInfo crashInfo) {
7546 // NOTE -- this must never acquire the ActivityManagerService lock,
7547 // otherwise the watchdog may be prevented from resetting the system.
7548
7549 final String dropboxTag = processClass(process) + "_" + eventType;
7550 final DropBoxManager dbox = (DropBoxManager)
7551 mContext.getSystemService(Context.DROPBOX_SERVICE);
7552
7553 // Exit early if the dropbox isn't configured to accept this report type.
7554 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7555
7556 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07007557 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08007558 if (activity != null) {
7559 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
7560 }
7561 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
7562 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
7563 }
7564 if (parent != null && parent != activity) {
7565 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
7566 }
7567 if (subject != null) {
7568 sb.append("Subject: ").append(subject).append("\n");
7569 }
7570 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02007571 if (Debug.isDebuggerConnected()) {
7572 sb.append("Debugger: Connected\n");
7573 }
Dan Egnora455d192010-03-12 08:52:28 -08007574 sb.append("\n");
7575
7576 // Do the rest in a worker thread to avoid blocking the caller on I/O
7577 // (After this point, we shouldn't access AMS internal data structures.)
7578 Thread worker = new Thread("Error dump: " + dropboxTag) {
7579 @Override
7580 public void run() {
7581 if (report != null) {
7582 sb.append(report);
7583 }
7584 if (logFile != null) {
7585 try {
7586 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
7587 } catch (IOException e) {
7588 Slog.e(TAG, "Error reading " + logFile, e);
7589 }
7590 }
7591 if (crashInfo != null && crashInfo.stackTrace != null) {
7592 sb.append(crashInfo.stackTrace);
7593 }
7594
7595 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
7596 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
7597 if (lines > 0) {
7598 sb.append("\n");
7599
7600 // Merge several logcat streams, and take the last N lines
7601 InputStreamReader input = null;
7602 try {
7603 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
7604 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
7605 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
7606
7607 try { logcat.getOutputStream().close(); } catch (IOException e) {}
7608 try { logcat.getErrorStream().close(); } catch (IOException e) {}
7609 input = new InputStreamReader(logcat.getInputStream());
7610
7611 int num;
7612 char[] buf = new char[8192];
7613 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
7614 } catch (IOException e) {
7615 Slog.e(TAG, "Error running logcat", e);
7616 } finally {
7617 if (input != null) try { input.close(); } catch (IOException e) {}
7618 }
7619 }
7620
7621 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08007622 }
Dan Egnora455d192010-03-12 08:52:28 -08007623 };
7624
7625 if (process == null || process.pid == MY_PID) {
7626 worker.run(); // We may be about to die -- need to run this synchronously
7627 } else {
7628 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08007629 }
7630 }
7631
7632 /**
7633 * Bring up the "unexpected error" dialog box for a crashing app.
7634 * Deal with edge cases (intercepts from instrumented applications,
7635 * ActivityController, error intent receivers, that sort of thing).
7636 * @param r the application crashing
7637 * @param crashInfo describing the failure
7638 */
7639 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007640 long timeMillis = System.currentTimeMillis();
7641 String shortMsg = crashInfo.exceptionClassName;
7642 String longMsg = crashInfo.exceptionMessage;
7643 String stackTrace = crashInfo.stackTrace;
7644 if (shortMsg != null && longMsg != null) {
7645 longMsg = shortMsg + ": " + longMsg;
7646 } else if (shortMsg != null) {
7647 longMsg = shortMsg;
7648 }
7649
Dan Egnor60d87622009-12-16 16:32:58 -08007650 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007651 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007652 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007653 try {
7654 String name = r != null ? r.processName : null;
7655 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08007656 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08007657 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007658 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007659 + " at watcher's request");
7660 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08007661 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007662 }
7663 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007664 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 }
7666 }
7667
7668 final long origId = Binder.clearCallingIdentity();
7669
7670 // If this process is running instrumentation, finish it.
7671 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007672 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007673 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08007674 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
7675 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007676 Bundle info = new Bundle();
7677 info.putString("shortMsg", shortMsg);
7678 info.putString("longMsg", longMsg);
7679 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
7680 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007681 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007682 }
7683
Dan Egnor60d87622009-12-16 16:32:58 -08007684 // If we can't identify the process or it's already exceeded its crash quota,
7685 // quit right away without showing a crash dialog.
7686 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007687 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08007688 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007689 }
7690
7691 Message msg = Message.obtain();
7692 msg.what = SHOW_ERROR_MSG;
7693 HashMap data = new HashMap();
7694 data.put("result", result);
7695 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007696 msg.obj = data;
7697 mHandler.sendMessage(msg);
7698
7699 Binder.restoreCallingIdentity(origId);
7700 }
7701
7702 int res = result.get();
7703
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007704 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007705 synchronized (this) {
7706 if (r != null) {
7707 mProcessCrashTimes.put(r.info.processName, r.info.uid,
7708 SystemClock.uptimeMillis());
7709 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007710 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08007711 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007712 }
7713 }
7714
7715 if (appErrorIntent != null) {
7716 try {
7717 mContext.startActivity(appErrorIntent);
7718 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007719 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007722 }
Dan Egnorb7f03672009-12-09 16:22:32 -08007723
7724 Intent createAppErrorIntentLocked(ProcessRecord r,
7725 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
7726 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007727 if (report == null) {
7728 return null;
7729 }
7730 Intent result = new Intent(Intent.ACTION_APP_ERROR);
7731 result.setComponent(r.errorReportReceiver);
7732 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
7733 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
7734 return result;
7735 }
7736
Dan Egnorb7f03672009-12-09 16:22:32 -08007737 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
7738 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007739 if (r.errorReportReceiver == null) {
7740 return null;
7741 }
7742
7743 if (!r.crashing && !r.notResponding) {
7744 return null;
7745 }
7746
Dan Egnorb7f03672009-12-09 16:22:32 -08007747 ApplicationErrorReport report = new ApplicationErrorReport();
7748 report.packageName = r.info.packageName;
7749 report.installerPackageName = r.errorReportReceiver.getPackageName();
7750 report.processName = r.processName;
7751 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01007752 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007753
Dan Egnorb7f03672009-12-09 16:22:32 -08007754 if (r.crashing) {
7755 report.type = ApplicationErrorReport.TYPE_CRASH;
7756 report.crashInfo = crashInfo;
7757 } else if (r.notResponding) {
7758 report.type = ApplicationErrorReport.TYPE_ANR;
7759 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007760
Dan Egnorb7f03672009-12-09 16:22:32 -08007761 report.anrInfo.activity = r.notRespondingReport.tag;
7762 report.anrInfo.cause = r.notRespondingReport.shortMsg;
7763 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007764 }
7765
Dan Egnorb7f03672009-12-09 16:22:32 -08007766 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02007767 }
7768
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007769 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
7770 // assume our apps are happy - lazy create the list
7771 List<ActivityManager.ProcessErrorStateInfo> errList = null;
7772
7773 synchronized (this) {
7774
7775 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007776 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7777 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007778 if ((app.thread != null) && (app.crashing || app.notResponding)) {
7779 // This one's in trouble, so we'll generate a report for it
7780 // crashes are higher priority (in case there's a crash *and* an anr)
7781 ActivityManager.ProcessErrorStateInfo report = null;
7782 if (app.crashing) {
7783 report = app.crashingReport;
7784 } else if (app.notResponding) {
7785 report = app.notRespondingReport;
7786 }
7787
7788 if (report != null) {
7789 if (errList == null) {
7790 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
7791 }
7792 errList.add(report);
7793 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007794 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007795 " crashing = " + app.crashing +
7796 " notResponding = " + app.notResponding);
7797 }
7798 }
7799 }
7800 }
7801
7802 return errList;
7803 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07007804
7805 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007806 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007807 if (currApp != null) {
7808 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
7809 }
7810 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007811 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
7812 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007813 } else if (adj >= ProcessList.HOME_APP_ADJ) {
7814 if (currApp != null) {
7815 currApp.lru = 0;
7816 }
7817 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007818 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07007819 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
7820 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
7821 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
7822 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
7823 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
7824 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
7825 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
7826 } else {
7827 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
7828 }
7829 }
7830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007831 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
7832 // Lazy instantiation of list
7833 List<ActivityManager.RunningAppProcessInfo> runList = null;
7834 synchronized (this) {
7835 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08007836 for (int i=mLruProcesses.size()-1; i>=0; i--) {
7837 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007838 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
7839 // Generate process state info for running application
7840 ActivityManager.RunningAppProcessInfo currApp =
7841 new ActivityManager.RunningAppProcessInfo(app.processName,
7842 app.pid, app.getPackageList());
Dianne Hackborneb034652009-09-07 00:49:58 -07007843 currApp.uid = app.info.uid;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007844 if (mHeavyWeightProcess == app) {
Dianne Hackborn482566e2010-09-03 12:51:28 -07007845 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
Dianne Hackbornbaf42c62010-06-24 11:23:39 -07007846 }
Dianne Hackborn42499172010-10-15 18:45:07 -07007847 if (app.persistent) {
7848 currApp.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
7849 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007850 int adj = app.curAdj;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007851 currApp.importance = oomAdjToImportance(adj, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007852 currApp.importanceReasonCode = app.adjTypeCode;
7853 if (app.adjSource instanceof ProcessRecord) {
7854 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07007855 currApp.importanceReasonImportance = oomAdjToImportance(
7856 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007857 } else if (app.adjSource instanceof ActivityRecord) {
7858 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07007859 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
7860 }
7861 if (app.adjTarget instanceof ComponentName) {
7862 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
7863 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007864 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007865 // + " lru=" + currApp.lru);
7866 if (runList == null) {
7867 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
7868 }
7869 runList.add(currApp);
7870 }
7871 }
7872 }
7873 return runList;
7874 }
7875
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007876 public List<ApplicationInfo> getRunningExternalApplications() {
7877 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
7878 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
7879 if (runningApps != null && runningApps.size() > 0) {
7880 Set<String> extList = new HashSet<String>();
7881 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
7882 if (app.pkgList != null) {
7883 for (String pkg : app.pkgList) {
7884 extList.add(pkg);
7885 }
7886 }
7887 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007888 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07007889 for (String pkg : extList) {
7890 try {
7891 ApplicationInfo info = pm.getApplicationInfo(pkg, 0);
7892 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
7893 retList.add(info);
7894 }
7895 } catch (RemoteException e) {
7896 }
7897 }
7898 }
7899 return retList;
7900 }
7901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007902 @Override
7903 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007904 if (checkCallingPermission(android.Manifest.permission.DUMP)
7905 != PackageManager.PERMISSION_GRANTED) {
7906 pw.println("Permission Denial: can't dump ActivityManager from from pid="
7907 + Binder.getCallingPid()
7908 + ", uid=" + Binder.getCallingUid()
7909 + " without permission "
7910 + android.Manifest.permission.DUMP);
7911 return;
7912 }
7913
7914 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007915 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007916 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007917
7918 int opti = 0;
7919 while (opti < args.length) {
7920 String opt = args[opti];
7921 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
7922 break;
7923 }
7924 opti++;
7925 if ("-a".equals(opt)) {
7926 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007927 } else if ("-c".equals(opt)) {
7928 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007929 } else if ("-h".equals(opt)) {
7930 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007931 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007932 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007933 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007934 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
7935 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
7936 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07007937 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007938 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
7939 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007940 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007941 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007942 pw.println(" all: dump all activities");
7943 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007944 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07007945 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
7946 pw.println(" a partial substring in a component name, a");
7947 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07007948 pw.println(" -a: include all available server state.");
7949 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007950 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007951 } else {
7952 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007953 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007954 }
7955
7956 // Is the caller requesting to dump a particular piece of data?
7957 if (opti < args.length) {
7958 String cmd = args[opti];
7959 opti++;
7960 if ("activities".equals(cmd) || "a".equals(cmd)) {
7961 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007962 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007963 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007964 return;
7965 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007966 String[] newArgs;
7967 String name;
7968 if (opti >= args.length) {
7969 name = null;
7970 newArgs = EMPTY_STRING_ARRAY;
7971 } else {
7972 name = args[opti];
7973 opti++;
7974 newArgs = new String[args.length - opti];
7975 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
7976 args.length - opti);
7977 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007978 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007979 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007980 }
7981 return;
7982 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007983 String[] newArgs;
7984 String name;
7985 if (opti >= args.length) {
7986 name = null;
7987 newArgs = EMPTY_STRING_ARRAY;
7988 } else {
7989 name = args[opti];
7990 opti++;
7991 newArgs = new String[args.length - opti];
7992 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
7993 args.length - opti);
7994 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007995 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08007996 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08007997 }
7998 return;
7999 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008000 String[] newArgs;
8001 String name;
8002 if (opti >= args.length) {
8003 name = null;
8004 newArgs = EMPTY_STRING_ARRAY;
8005 } else {
8006 name = args[opti];
8007 opti++;
8008 newArgs = new String[args.length - opti];
8009 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8010 args.length - opti);
8011 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008012 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008013 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008014 }
8015 return;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008016 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8017 synchronized (this) {
8018 dumpOomLocked(fd, pw, args, opti, true);
8019 }
8020 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008021 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8022 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008023 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008024 }
8025 return;
8026 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008027 String[] newArgs;
8028 String name;
8029 if (opti >= args.length) {
8030 name = null;
8031 newArgs = EMPTY_STRING_ARRAY;
8032 } else {
8033 name = args[opti];
8034 opti++;
8035 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008036 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8037 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008038 }
8039 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8040 pw.println("No services match: " + name);
8041 pw.println("Use -h for help.");
8042 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008043 return;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008044 } else if ("package".equals(cmd)) {
8045 String[] newArgs;
8046 if (opti >= args.length) {
8047 pw.println("package: no package name specified");
8048 pw.println("Use -h for help.");
8049 return;
8050 } else {
8051 dumpPackage = args[opti];
8052 opti++;
8053 newArgs = new String[args.length - opti];
8054 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8055 args.length - opti);
8056 args = newArgs;
8057 opti = 0;
8058 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008059 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8060 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008061 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008062 }
8063 return;
Dianne Hackborn625ac272010-09-17 18:29:22 -07008064 } else {
8065 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008066 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8067 pw.println("Bad activity command, or no activities match: " + cmd);
8068 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008069 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008070 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008072 }
8073
8074 // No piece of data specified, dump everything.
8075 synchronized (this) {
8076 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008077 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008078 if (needSep) {
8079 pw.println(" ");
8080 }
8081 if (dumpAll) {
8082 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008083 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008084 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008085 if (needSep) {
8086 pw.println(" ");
8087 }
8088 if (dumpAll) {
8089 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008090 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008091 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008092 if (needSep) {
8093 pw.println(" ");
8094 }
8095 if (dumpAll) {
8096 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008097 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008098 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008099 if (needSep) {
8100 pw.println(" ");
8101 }
8102 if (dumpAll) {
8103 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008104 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008105 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008106 if (needSep) {
8107 pw.println(" ");
8108 }
8109 if (dumpAll) {
8110 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008111 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008112 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008113 }
8114 }
8115
8116 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008117 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008118 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8119 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008120 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8121 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008122 pw.println(" ");
8123 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008124 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8125 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008126 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008127 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008128 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008129 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008130 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008131 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008132 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008133 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008134 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008135 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008136 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008137 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008138 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8139 pw.println(" ");
8140 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008141 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008142 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008143 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008144 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008145 pw.println(" ");
8146 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008147 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008148 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008151 pw.println(" ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008152 if (mMainStack.mPausingActivity != null) {
8153 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
8154 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008155 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008156 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008157 if (dumpAll) {
8158 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8159 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008160 pw.println(" mDismissKeyguardOnNextActivity: "
8161 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008162 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008163
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008164 if (mRecentTasks.size() > 0) {
8165 pw.println();
8166 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008167
8168 final int N = mRecentTasks.size();
8169 for (int i=0; i<N; i++) {
8170 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008171 if (dumpPackage != null) {
8172 if (tr.realActivity == null ||
8173 !dumpPackage.equals(tr.realActivity)) {
8174 continue;
8175 }
8176 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008177 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8178 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008179 if (dumpAll) {
8180 mRecentTasks.get(i).dump(pw, " ");
8181 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008182 }
8183 }
8184
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008185 if (dumpAll) {
8186 pw.println(" ");
8187 pw.println(" mCurTask: " + mCurTask);
8188 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008189
8190 return true;
8191 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008192
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008193 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008194 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008195 boolean needSep = false;
8196 int numPers = 0;
8197
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008198 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8199
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008200 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008201 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8202 final int NA = procs.size();
8203 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008204 ProcessRecord r = procs.valueAt(ia);
8205 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8206 continue;
8207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008208 if (!needSep) {
8209 pw.println(" All known processes:");
8210 needSep = true;
8211 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008212 pw.print(r.persistent ? " *PERS*" : " *APP*");
8213 pw.print(" UID "); pw.print(procs.keyAt(ia));
8214 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008215 r.dump(pw, " ");
8216 if (r.persistent) {
8217 numPers++;
8218 }
8219 }
8220 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008221 }
8222
8223 if (mLruProcesses.size() > 0) {
8224 if (needSep) pw.println(" ");
8225 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008226 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008227 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008228 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008229 needSep = true;
8230 }
8231
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008232 if (dumpAll) {
8233 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008234 boolean printed = false;
8235 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8236 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8237 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8238 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008239 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008240 if (!printed) {
8241 if (needSep) pw.println(" ");
8242 needSep = true;
8243 pw.println(" PID mappings:");
8244 printed = true;
8245 }
8246 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8247 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008248 }
8249 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008250 }
8251
8252 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008253 synchronized (mPidsSelfLocked) {
8254 boolean printed = false;
8255 for (int i=0; i<mForegroundProcesses.size(); i++) {
8256 ProcessRecord r = mPidsSelfLocked.get(
8257 mForegroundProcesses.valueAt(i).pid);
8258 if (dumpPackage != null && (r == null
8259 || !dumpPackage.equals(r.info.packageName))) {
8260 continue;
8261 }
8262 if (!printed) {
8263 if (needSep) pw.println(" ");
8264 needSep = true;
8265 pw.println(" Foreground Processes:");
8266 printed = true;
8267 }
8268 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8269 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008271 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008272 }
8273
8274 if (mPersistentStartingProcesses.size() > 0) {
8275 if (needSep) pw.println(" ");
8276 needSep = true;
8277 pw.println(" Persisent processes that are starting:");
8278 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008279 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008280 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008281
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008282 if (mRemovedProcesses.size() > 0) {
8283 if (needSep) pw.println(" ");
8284 needSep = true;
8285 pw.println(" Processes that are being removed:");
8286 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008287 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008288 }
8289
8290 if (mProcessesOnHold.size() > 0) {
8291 if (needSep) pw.println(" ");
8292 needSep = true;
8293 pw.println(" Processes that are on old until the system is ready:");
8294 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008295 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008296 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008297
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008298 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008299
8300 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008301 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008302 long now = SystemClock.uptimeMillis();
8303 for (Map.Entry<String, SparseArray<Long>> procs
8304 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008305 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008306 SparseArray<Long> uids = procs.getValue();
8307 final int N = uids.size();
8308 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008309 int puid = uids.keyAt(i);
8310 ProcessRecord r = mProcessNames.get(pname, puid);
8311 if (dumpPackage != null && (r == null
8312 || !dumpPackage.equals(r.info.packageName))) {
8313 continue;
8314 }
8315 if (!printed) {
8316 if (needSep) pw.println(" ");
8317 needSep = true;
8318 pw.println(" Time since processes crashed:");
8319 printed = true;
8320 }
8321 pw.print(" Process "); pw.print(pname);
8322 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008323 pw.print(": last crashed ");
8324 pw.print((now-uids.valueAt(i)));
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008325 pw.println(" ms ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07008326 }
8327 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008329
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008330 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008331 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008332 for (Map.Entry<String, SparseArray<Long>> procs
8333 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008334 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008335 SparseArray<Long> uids = procs.getValue();
8336 final int N = uids.size();
8337 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008338 int puid = uids.keyAt(i);
8339 ProcessRecord r = mProcessNames.get(pname, puid);
8340 if (dumpPackage != null && (r == null
8341 || !dumpPackage.equals(r.info.packageName))) {
8342 continue;
8343 }
8344 if (!printed) {
8345 if (needSep) pw.println(" ");
8346 needSep = true;
8347 pw.println(" Bad processes:");
8348 }
8349 pw.print(" Bad process "); pw.print(pname);
8350 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008351 pw.print(": crashed at time ");
8352 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008353 }
8354 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008356
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008357 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008358 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008359 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn860755f2010-06-03 18:47:52 -07008360 if (mHeavyWeightProcess != null) {
8361 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8362 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008363 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008364 if (dumpAll) {
8365 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07008366 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008367 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008368 for (Map.Entry<String, Integer> entry
8369 : mCompatModePackages.getPackages().entrySet()) {
8370 String pkg = entry.getKey();
8371 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008372 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
8373 continue;
8374 }
8375 if (!printed) {
8376 pw.println(" mScreenCompatPackages:");
8377 printed = true;
8378 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07008379 pw.print(" "); pw.print(pkg); pw.print(": ");
8380 pw.print(mode); pw.println();
8381 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07008382 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008383 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008384 pw.println(" mSleeping=" + mSleeping + " mShuttingDown=" + mShuttingDown);
8385 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
8386 || mOrigWaitForDebugger) {
8387 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
8388 + " mDebugTransient=" + mDebugTransient
8389 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
8390 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07008391 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
8392 || mProfileFd != null) {
8393 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
8394 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
8395 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
8396 + mAutoStopProfiler);
8397 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008398 if (mAlwaysFinishActivities || mController != null) {
8399 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
8400 + " mController=" + mController);
8401 }
8402 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008403 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008404 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07008405 + " mProcessesReady=" + mProcessesReady
8406 + " mSystemReady=" + mSystemReady);
8407 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008408 + " mBooted=" + mBooted
8409 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008410 pw.print(" mLastPowerCheckRealtime=");
8411 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
8412 pw.println("");
8413 pw.print(" mLastPowerCheckUptime=");
8414 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
8415 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008416 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
8417 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07008418 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008419 pw.println(" mNumServiceProcs=" + mNumServiceProcs
8420 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008421 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008422
8423 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008424 }
8425
Dianne Hackborn287952c2010-09-22 22:34:31 -07008426 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008427 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008428 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008429 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008430 long now = SystemClock.uptimeMillis();
8431 for (int i=0; i<mProcessesToGc.size(); i++) {
8432 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008433 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
8434 continue;
8435 }
8436 if (!printed) {
8437 if (needSep) pw.println(" ");
8438 needSep = true;
8439 pw.println(" Processes that are waiting to GC:");
8440 printed = true;
8441 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008442 pw.print(" Process "); pw.println(proc);
8443 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
8444 pw.print(", last gced=");
8445 pw.print(now-proc.lastRequestedGc);
8446 pw.print(" ms ago, last lowMem=");
8447 pw.print(now-proc.lastLowMemory);
8448 pw.println(" ms ago");
8449
8450 }
8451 }
8452 return needSep;
8453 }
8454
8455 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
8456 int opti, boolean dumpAll) {
8457 boolean needSep = false;
8458
8459 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008460 if (needSep) pw.println(" ");
8461 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008462 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07008463 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008464 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008465 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
8466 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
8467 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
8468 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
8469 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008470 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008471 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008472 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008473 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07008474 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008475 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07008476
8477 if (needSep) pw.println(" ");
8478 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07008479 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07008480 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008481 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008482 needSep = true;
8483 }
8484
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008485 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008486
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008487 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008488 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07008489 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008490 if (mHeavyWeightProcess != null) {
8491 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
8492 }
8493
8494 return true;
8495 }
8496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008497 /**
8498 * There are three ways to call this:
8499 * - no service specified: dump all the services
8500 * - a flattened component name that matched an existing service was specified as the
8501 * first arg: dump that one service
8502 * - the first arg isn't the flattened component name of an existing service:
8503 * dump all services whose component contains the first arg as a substring
8504 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008505 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8506 int opti, boolean dumpAll) {
8507 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008509 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008510 synchronized (this) {
8511 for (ServiceRecord r1 : mServices.values()) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008512 services.add(r1);
8513 }
8514 }
8515 } else {
8516 ComponentName componentName = name != null
8517 ? ComponentName.unflattenFromString(name) : null;
8518 int objectId = 0;
8519 if (componentName == null) {
8520 // Not a '/' separated full component name; maybe an object ID?
8521 try {
8522 objectId = Integer.parseInt(name, 16);
8523 name = null;
8524 componentName = null;
8525 } catch (RuntimeException e) {
8526 }
8527 }
8528
8529 synchronized (this) {
8530 for (ServiceRecord r1 : mServices.values()) {
8531 if (componentName != null) {
8532 if (r1.name.equals(componentName)) {
8533 services.add(r1);
8534 }
8535 } else if (name != null) {
8536 if (r1.name.flattenToString().contains(name)) {
8537 services.add(r1);
8538 }
8539 } else if (System.identityHashCode(r1) == objectId) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07008540 services.add(r1);
8541 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008542 }
8543 }
8544 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008545
8546 if (services.size() <= 0) {
8547 return false;
8548 }
8549
8550 boolean needSep = false;
8551 for (int i=0; i<services.size(); i++) {
8552 if (needSep) {
8553 pw.println();
8554 }
8555 needSep = true;
8556 dumpService("", fd, pw, services.get(i), args, dumpAll);
8557 }
8558 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008559 }
8560
8561 /**
8562 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
8563 * there is a thread associated with the service.
8564 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008565 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
8566 final ServiceRecord r, String[] args, boolean dumpAll) {
8567 String innerPrefix = prefix + " ";
8568 synchronized (this) {
8569 pw.print(prefix); pw.print("SERVICE ");
8570 pw.print(r.shortName); pw.print(" ");
8571 pw.print(Integer.toHexString(System.identityHashCode(r)));
8572 pw.print(" pid=");
8573 if (r.app != null) pw.println(r.app.pid);
8574 else pw.println("(not running)");
8575 if (dumpAll) {
8576 r.dump(pw, innerPrefix);
8577 }
8578 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008580 pw.print(prefix); pw.println(" Client:");
8581 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008582 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008583 TransferPipe tp = new TransferPipe();
8584 try {
8585 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
8586 tp.setBufferPrefix(prefix + " ");
8587 tp.go(fd);
8588 } finally {
8589 tp.kill();
8590 }
8591 } catch (IOException e) {
8592 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008593 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008594 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008595 }
8596 }
8597 }
8598
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008599 static class ItemMatcher {
8600 ArrayList<ComponentName> components;
8601 ArrayList<String> strings;
8602 ArrayList<Integer> objects;
8603 boolean all;
8604
8605 ItemMatcher() {
8606 all = true;
8607 }
8608
8609 void build(String name) {
8610 ComponentName componentName = ComponentName.unflattenFromString(name);
8611 if (componentName != null) {
8612 if (components == null) {
8613 components = new ArrayList<ComponentName>();
8614 }
8615 components.add(componentName);
8616 all = false;
8617 } else {
8618 int objectId = 0;
8619 // Not a '/' separated full component name; maybe an object ID?
8620 try {
8621 objectId = Integer.parseInt(name, 16);
8622 if (objects == null) {
8623 objects = new ArrayList<Integer>();
8624 }
8625 objects.add(objectId);
8626 all = false;
8627 } catch (RuntimeException e) {
8628 // Not an integer; just do string match.
8629 if (strings == null) {
8630 strings = new ArrayList<String>();
8631 }
8632 strings.add(name);
8633 all = false;
8634 }
8635 }
8636 }
8637
8638 int build(String[] args, int opti) {
8639 for (; opti<args.length; opti++) {
8640 String name = args[opti];
8641 if ("--".equals(name)) {
8642 return opti+1;
8643 }
8644 build(name);
8645 }
8646 return opti;
8647 }
8648
8649 boolean match(Object object, ComponentName comp) {
8650 if (all) {
8651 return true;
8652 }
8653 if (components != null) {
8654 for (int i=0; i<components.size(); i++) {
8655 if (components.get(i).equals(comp)) {
8656 return true;
8657 }
8658 }
8659 }
8660 if (objects != null) {
8661 for (int i=0; i<objects.size(); i++) {
8662 if (System.identityHashCode(object) == objects.get(i)) {
8663 return true;
8664 }
8665 }
8666 }
8667 if (strings != null) {
8668 String flat = comp.flattenToString();
8669 for (int i=0; i<strings.size(); i++) {
8670 if (flat.contains(strings.get(i))) {
8671 return true;
8672 }
8673 }
8674 }
8675 return false;
8676 }
8677 }
8678
Dianne Hackborn625ac272010-09-17 18:29:22 -07008679 /**
8680 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008681 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07008682 * - the cmd arg isn't the flattened component name of an existing activity:
8683 * dump all activity whose component contains the cmd as a substring
8684 * - A hex number of the ActivityRecord object instance.
8685 */
8686 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
8687 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008688 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008689
8690 if ("all".equals(name)) {
8691 synchronized (this) {
8692 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07008693 activities.add(r1);
8694 }
8695 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07008696 } else if ("top".equals(name)) {
8697 synchronized (this) {
8698 final int N = mMainStack.mHistory.size();
8699 if (N > 0) {
8700 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
8701 }
8702 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008703 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008704 ItemMatcher matcher = new ItemMatcher();
8705 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008706
8707 synchronized (this) {
8708 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008709 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008710 activities.add(r1);
8711 }
8712 }
8713 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008714 }
8715
8716 if (activities.size() <= 0) {
8717 return false;
8718 }
8719
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008720 String[] newArgs = new String[args.length - opti];
8721 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8722
Dianne Hackborn30d71892010-12-11 10:37:55 -08008723 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008724 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08008725 for (int i=activities.size()-1; i>=0; i--) {
8726 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008727 if (needSep) {
8728 pw.println();
8729 }
8730 needSep = true;
8731 synchronized (this) {
8732 if (lastTask != r.task) {
8733 lastTask = r.task;
8734 pw.print("TASK "); pw.print(lastTask.affinity);
8735 pw.print(" id="); pw.println(lastTask.taskId);
8736 if (dumpAll) {
8737 lastTask.dump(pw, " ");
8738 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08008739 }
8740 }
8741 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008742 }
8743 return true;
8744 }
8745
8746 /**
8747 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
8748 * there is a thread associated with the activity.
8749 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08008750 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008751 final ActivityRecord r, String[] args, boolean dumpAll) {
8752 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08008753 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008754 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
8755 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
8756 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08008757 if (r.app != null) pw.println(r.app.pid);
8758 else pw.println("(not running)");
8759 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008760 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008761 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008762 }
8763 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008764 // flush anything that is already in the PrintWriter since the thread is going
8765 // to write to the file descriptor directly
8766 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07008767 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008768 TransferPipe tp = new TransferPipe();
8769 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08008770 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
8771 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008772 tp.go(fd);
8773 } finally {
8774 tp.kill();
8775 }
8776 } catch (IOException e) {
8777 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07008778 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008779 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008780 }
8781 }
8782 }
8783
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008784 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008785 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008786 boolean needSep = false;
8787
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008788 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008789 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008791 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008792 Iterator it = mRegisteredReceivers.values().iterator();
8793 while (it.hasNext()) {
8794 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008795 if (dumpPackage != null && (r.app == null ||
8796 !dumpPackage.equals(r.app.info.packageName))) {
8797 continue;
8798 }
8799 if (!printed) {
8800 pw.println(" Registered Receivers:");
8801 needSep = true;
8802 printed = true;
8803 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008804 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008805 r.dump(pw, " ");
8806 }
8807 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008808
8809 if (mReceiverResolver.dump(pw, needSep ?
8810 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
8811 " ", dumpPackage, false)) {
8812 needSep = true;
8813 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008814 }
8815
8816 if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
8817 || mPendingBroadcast != null) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008818 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008819 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008820 BroadcastRecord br = mParallelBroadcasts.get(i);
8821 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8822 continue;
8823 }
8824 if (!printed) {
8825 if (needSep) {
8826 pw.println();
8827 }
8828 needSep = true;
8829 pw.println(" Active broadcasts:");
8830 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008831 pw.println(" Broadcast #" + i + ":");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008832 br.dump(pw, " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008833 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008834 printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008835 for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008836 BroadcastRecord br = mOrderedBroadcasts.get(i);
8837 if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
8838 continue;
8839 }
8840 if (!printed) {
8841 if (needSep) {
8842 pw.println();
8843 }
8844 needSep = true;
8845 pw.println(" Active ordered broadcasts:");
8846 }
8847 pw.println(" Ordered Broadcast #" + i + ":");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008848 mOrderedBroadcasts.get(i).dump(pw, " ");
8849 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008850 if (dumpPackage == null || (mPendingBroadcast != null
8851 && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
8852 if (needSep) {
8853 pw.println();
8854 }
8855 pw.println(" Pending broadcast:");
8856 if (mPendingBroadcast != null) {
8857 mPendingBroadcast.dump(pw, " ");
8858 } else {
8859 pw.println(" (null)");
8860 }
8861 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008862 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008863 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008864
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008865 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008866 for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
8867 BroadcastRecord r = mBroadcastHistory[i];
8868 if (r == null) {
8869 break;
8870 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008871 if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
8872 continue;
8873 }
8874 if (!printed) {
8875 if (needSep) {
8876 pw.println();
8877 }
8878 needSep = true;
8879 pw.println(" Historical broadcasts:");
8880 printed = true;
8881 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008882 if (dumpAll) {
8883 pw.print(" Historical Broadcast #"); pw.print(i); pw.println(":");
8884 r.dump(pw, " ");
8885 } else {
8886 if (i >= 50) {
8887 pw.println(" ...");
Dianne Hackborn12527f92009-11-11 17:39:50 -08008888 break;
8889 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008890 pw.print(" #"); pw.print(i); pw.print(": "); pw.println(r);
Dianne Hackborn12527f92009-11-11 17:39:50 -08008891 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008892 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008893 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008894
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008895 if (mStickyBroadcasts != null && dumpPackage == null) {
8896 if (needSep) {
8897 pw.println();
8898 }
8899 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008900 pw.println(" Sticky broadcasts:");
8901 StringBuilder sb = new StringBuilder(128);
8902 for (Map.Entry<String, ArrayList<Intent>> ent
8903 : mStickyBroadcasts.entrySet()) {
8904 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008905 if (dumpAll) {
8906 pw.println(":");
8907 ArrayList<Intent> intents = ent.getValue();
8908 final int N = intents.size();
8909 for (int i=0; i<N; i++) {
8910 sb.setLength(0);
8911 sb.append(" Intent: ");
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008912 intents.get(i).toShortString(sb, false, true, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008913 pw.println(sb.toString());
8914 Bundle bundle = intents.get(i).getExtras();
8915 if (bundle != null) {
8916 pw.print(" ");
8917 pw.println(bundle.toString());
8918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008919 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008920 } else {
8921 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008922 }
8923 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008924 needSep = true;
8925 }
8926
8927 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008928 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008929 pw.println(" mBroadcastsScheduled=" + mBroadcastsScheduled);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008930 pw.println(" mHandler:");
8931 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008932 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008933 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008934
8935 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008936 }
8937
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008938 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008939 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008940 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008941
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008942 ItemMatcher matcher = new ItemMatcher();
8943 matcher.build(args, opti);
8944
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008945 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
8946 if (mServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008947 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008948 long nowReal = SystemClock.elapsedRealtime();
8949 Iterator<ServiceRecord> it = mServices.values().iterator();
8950 needSep = false;
8951 while (it.hasNext()) {
8952 ServiceRecord r = it.next();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008953 if (!matcher.match(r, r.name)) {
8954 continue;
8955 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008956 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
8957 continue;
8958 }
8959 if (!printed) {
8960 pw.println(" Active services:");
8961 printed = true;
8962 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008963 if (needSep) {
8964 pw.println();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008965 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008966 pw.print(" * "); pw.println(r);
8967 if (dumpAll) {
8968 r.dump(pw, " ");
8969 needSep = true;
8970 } else {
8971 pw.print(" app="); pw.println(r.app);
8972 pw.print(" created=");
8973 TimeUtils.formatDuration(r.createTime, nowReal, pw);
8974 pw.print(" started="); pw.print(r.startRequested);
8975 pw.print(" connections="); pw.println(r.connections.size());
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08008976 if (r.connections.size() > 0) {
8977 pw.println(" Connections:");
8978 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
8979 for (int i=0; i<clist.size(); i++) {
8980 ConnectionRecord conn = clist.get(i);
8981 pw.print(" ");
8982 pw.print(conn.binding.intent.intent.getIntent().toShortString(
8983 false, false, false));
8984 pw.print(" -> ");
8985 ProcessRecord proc = conn.binding.client;
8986 pw.println(proc != null ? proc.toShortString() : "null");
8987 }
8988 }
8989 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008990 }
8991 if (dumpClient && r.app != null && r.app.thread != null) {
8992 pw.println(" Client:");
8993 pw.flush();
8994 try {
8995 TransferPipe tp = new TransferPipe();
8996 try {
8997 r.app.thread.dumpService(
8998 tp.getWriteFd().getFileDescriptor(), r, args);
8999 tp.setBufferPrefix(" ");
9000 // Short timeout, since blocking here can
9001 // deadlock with the application.
9002 tp.go(fd, 2000);
9003 } finally {
9004 tp.kill();
9005 }
9006 } catch (IOException e) {
9007 pw.println(" Failure while dumping the service: " + e);
9008 } catch (RemoteException e) {
9009 pw.println(" Got a RemoteException while dumping the service");
9010 }
9011 needSep = true;
9012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009013 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009014 needSep = printed;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009016
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009017 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009018 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009019 for (int i=0; i<mPendingServices.size(); i++) {
9020 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009021 if (!matcher.match(r, r.name)) {
9022 continue;
9023 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009024 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9025 continue;
9026 }
9027 if (!printed) {
9028 if (needSep) pw.println(" ");
9029 needSep = true;
9030 pw.println(" Pending services:");
9031 printed = true;
9032 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009033 pw.print(" * Pending "); pw.println(r);
9034 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009035 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009036 needSep = true;
9037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009038
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009039 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009040 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009041 for (int i=0; i<mRestartingServices.size(); i++) {
9042 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009043 if (!matcher.match(r, r.name)) {
9044 continue;
9045 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009046 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9047 continue;
9048 }
9049 if (!printed) {
9050 if (needSep) pw.println(" ");
9051 needSep = true;
9052 pw.println(" Restarting services:");
9053 printed = true;
9054 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009055 pw.print(" * Restarting "); pw.println(r);
9056 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009057 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009058 needSep = true;
9059 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009060
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009061 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009062 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009063 for (int i=0; i<mStoppingServices.size(); i++) {
9064 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009065 if (!matcher.match(r, r.name)) {
9066 continue;
9067 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009068 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9069 continue;
9070 }
9071 if (!printed) {
9072 if (needSep) pw.println(" ");
9073 needSep = true;
9074 pw.println(" Stopping services:");
9075 printed = true;
9076 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009077 pw.print(" * Stopping "); pw.println(r);
9078 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009079 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009080 needSep = true;
9081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009082
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009083 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009084 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009085 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009086 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009087 = mServiceConnections.values().iterator();
9088 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009089 ArrayList<ConnectionRecord> r = it.next();
9090 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009091 ConnectionRecord cr = r.get(i);
9092 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9093 continue;
9094 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009095 if (dumpPackage != null && (cr.binding.client == null
9096 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9097 continue;
9098 }
9099 if (!printed) {
9100 if (needSep) pw.println(" ");
9101 needSep = true;
9102 pw.println(" Connection bindings to services:");
9103 printed = true;
9104 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009105 pw.print(" * "); pw.println(cr);
9106 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009108 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009109 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009110 }
9111 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009112
9113 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009114 }
9115
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009116 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009117 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009118 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009119
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009120 ItemMatcher matcher = new ItemMatcher();
9121 matcher.build(args, opti);
9122
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009123 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
9124 if (mProvidersByClass.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009125 boolean printed = false;
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009126 Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009127 = mProvidersByClass.entrySet().iterator();
9128 while (it.hasNext()) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009129 Map.Entry<ComponentName, ContentProviderRecord> e = it.next();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009130 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009131 ComponentName comp = e.getKey();
9132 String cls = comp.getClassName();
9133 int end = cls.lastIndexOf('.');
9134 if (end > 0 && end < (cls.length()-2)) {
9135 cls = cls.substring(end+1);
9136 }
9137 if (!matcher.match(r, comp)) {
9138 continue;
9139 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009140 if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
9141 continue;
9142 }
9143 if (!printed) {
9144 if (needSep) pw.println(" ");
9145 needSep = true;
9146 pw.println(" Published content providers (by class):");
9147 printed = true;
9148 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009149 pw.print(" * "); pw.print(cls); pw.print(" (");
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009150 pw.print(comp.flattenToShortString()); pw.println(")");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009151 if (dumpAll) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009152 r.dump(pw, " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009153 } else {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009154 if (r.proc != null) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07009155 pw.print(" "); pw.println(r.proc);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009156 } else {
9157 pw.println();
9158 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009159 if (r.clients.size() > 0) {
9160 pw.println(" Clients:");
9161 for (ProcessRecord cproc : r.clients) {
9162 pw.print(" - "); pw.println(cproc);
9163 }
9164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009165 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009166 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009167 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009168
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009169 if (dumpAll) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009170 if (mProvidersByName.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009171 boolean printed = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -07009172 Iterator<Map.Entry<String, ContentProviderRecord>> it
9173 = mProvidersByName.entrySet().iterator();
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009174 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009175 Map.Entry<String, ContentProviderRecord> e = it.next();
9176 ContentProviderRecord r = e.getValue();
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009177 if (!matcher.match(r, r.name)) {
9178 continue;
9179 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009180 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9181 continue;
9182 }
9183 if (!printed) {
9184 if (needSep) pw.println(" ");
9185 needSep = true;
9186 pw.println(" Authority to provider mappings:");
9187 printed = true;
9188 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009189 pw.print(" "); pw.print(e.getKey()); pw.println(":");
9190 pw.print(" "); pw.println(r);
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009191 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009193 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009194
9195 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009196 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009197 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009198 ContentProviderRecord r = mLaunchingProviders.get(i);
9199 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9200 continue;
9201 }
9202 if (!printed) {
9203 if (needSep) pw.println(" ");
9204 needSep = true;
9205 pw.println(" Launching content providers:");
9206 printed = true;
9207 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009208 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009209 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009210 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009211 }
9212
9213 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009214 if (needSep) pw.println();
9215 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009216 pw.println("Granted Uri Permissions:");
9217 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9218 int uid = mGrantedUriPermissions.keyAt(i);
9219 HashMap<Uri, UriPermission> perms
9220 = mGrantedUriPermissions.valueAt(i);
9221 pw.print(" * UID "); pw.print(uid);
9222 pw.println(" holds:");
9223 for (UriPermission perm : perms.values()) {
9224 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009225 if (dumpAll) {
9226 perm.dump(pw, " ");
9227 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009228 }
9229 }
9230 needSep = true;
9231 }
9232
9233 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009234 }
9235
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009236 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009237 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009238 boolean needSep = false;
9239
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009240 if (mIntentSenderRecords.size() > 0) {
9241 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009242 Iterator<WeakReference<PendingIntentRecord>> it
9243 = mIntentSenderRecords.values().iterator();
9244 while (it.hasNext()) {
9245 WeakReference<PendingIntentRecord> ref = it.next();
9246 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009247 if (dumpPackage != null && (rec == null
9248 || !dumpPackage.equals(rec.key.packageName))) {
9249 continue;
9250 }
9251 if (!printed) {
9252 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9253 printed = true;
9254 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009255 needSep = true;
9256 if (rec != null) {
9257 pw.print(" * "); pw.println(rec);
9258 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009259 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009260 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009261 } else {
9262 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009263 }
9264 }
9265 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009266
9267 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009268 }
9269
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009270 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009271 String prefix, String label, boolean complete, boolean brief, boolean client,
9272 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009273 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009274 boolean needNL = false;
9275 final String innerPrefix = prefix + " ";
9276 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009277 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009278 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009279 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9280 continue;
9281 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009282 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009283 if (needNL) {
9284 pw.println(" ");
9285 needNL = false;
9286 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009287 if (lastTask != r.task) {
9288 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009289 pw.print(prefix);
9290 pw.print(full ? "* " : " ");
9291 pw.println(lastTask);
9292 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009293 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009294 } else if (complete) {
9295 // Complete + brief == give a summary. Isn't that obvious?!?
9296 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009297 pw.print(prefix); pw.print(" ");
9298 pw.println(lastTask.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009299 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009301 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009302 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9303 pw.print(" #"); pw.print(i); pw.print(": ");
9304 pw.println(r);
9305 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009306 r.dump(pw, innerPrefix);
9307 } else if (complete) {
9308 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009309 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009310 if (r.app != null) {
9311 pw.print(innerPrefix); pw.println(r.app);
9312 }
9313 }
9314 if (client && r.app != null && r.app.thread != null) {
9315 // flush anything that is already in the PrintWriter since the thread is going
9316 // to write to the file descriptor directly
9317 pw.flush();
9318 try {
9319 TransferPipe tp = new TransferPipe();
9320 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009321 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9322 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009323 // Short timeout, since blocking here can
9324 // deadlock with the application.
9325 tp.go(fd, 2000);
9326 } finally {
9327 tp.kill();
9328 }
9329 } catch (IOException e) {
9330 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9331 } catch (RemoteException e) {
9332 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9333 }
9334 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009335 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009336 }
9337 }
9338
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009339 private static String buildOomTag(String prefix, String space, int val, int base) {
9340 if (val == base) {
9341 if (space == null) return prefix;
9342 return prefix + " ";
9343 }
9344 return prefix + "+" + Integer.toString(val-base);
9345 }
9346
9347 private static final int dumpProcessList(PrintWriter pw,
9348 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009349 String prefix, String normalLabel, String persistentLabel,
9350 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009351 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009352 final int N = list.size()-1;
9353 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009354 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009355 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9356 continue;
9357 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009358 pw.println(String.format("%s%s #%2d: %s",
9359 prefix, (r.persistent ? persistentLabel : normalLabel),
9360 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009361 if (r.persistent) {
9362 numPers++;
9363 }
9364 }
9365 return numPers;
9366 }
9367
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009368 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009369 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009370 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009371 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009372
Dianne Hackborn905577f2011-09-07 18:31:28 -07009373 ArrayList<Pair<ProcessRecord, Integer>> list
9374 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9375 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009376 ProcessRecord r = origList.get(i);
9377 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9378 continue;
9379 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07009380 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9381 }
9382
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009383 if (list.size() <= 0) {
9384 return false;
9385 }
9386
Dianne Hackborn905577f2011-09-07 18:31:28 -07009387 Comparator<Pair<ProcessRecord, Integer>> comparator
9388 = new Comparator<Pair<ProcessRecord, Integer>>() {
9389 @Override
9390 public int compare(Pair<ProcessRecord, Integer> object1,
9391 Pair<ProcessRecord, Integer> object2) {
9392 if (object1.first.setAdj != object2.first.setAdj) {
9393 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9394 }
9395 if (object1.second.intValue() != object2.second.intValue()) {
9396 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9397 }
9398 return 0;
9399 }
9400 };
9401
9402 Collections.sort(list, comparator);
9403
Dianne Hackborn287952c2010-09-22 22:34:31 -07009404 final long curRealtime = SystemClock.elapsedRealtime();
9405 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9406 final long curUptime = SystemClock.uptimeMillis();
9407 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9408
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009409 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009410 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009411 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009412 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009413 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009414 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9415 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009416 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9417 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009418 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9419 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009420 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9421 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009422 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009423 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009424 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9425 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9426 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9427 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9428 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9429 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9430 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9431 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009432 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9433 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009434 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9435 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009436 } else {
9437 oomAdj = Integer.toString(r.setAdj);
9438 }
9439 String schedGroup;
9440 switch (r.setSchedGroup) {
9441 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9442 schedGroup = "B";
9443 break;
9444 case Process.THREAD_GROUP_DEFAULT:
9445 schedGroup = "F";
9446 break;
9447 default:
9448 schedGroup = Integer.toString(r.setSchedGroup);
9449 break;
9450 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009451 String foreground;
9452 if (r.foregroundActivities) {
9453 foreground = "A";
9454 } else if (r.foregroundServices) {
9455 foreground = "S";
9456 } else {
9457 foreground = " ";
9458 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009459 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009460 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009461 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9462 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009463 if (r.adjSource != null || r.adjTarget != null) {
9464 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009465 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009466 if (r.adjTarget instanceof ComponentName) {
9467 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9468 } else if (r.adjTarget != null) {
9469 pw.print(r.adjTarget.toString());
9470 } else {
9471 pw.print("{null}");
9472 }
9473 pw.print("<=");
9474 if (r.adjSource instanceof ProcessRecord) {
9475 pw.print("Proc{");
9476 pw.print(((ProcessRecord)r.adjSource).toShortString());
9477 pw.println("}");
9478 } else if (r.adjSource != null) {
9479 pw.println(r.adjSource.toString());
9480 } else {
9481 pw.println("{null}");
9482 }
9483 }
9484 if (inclDetails) {
9485 pw.print(prefix);
9486 pw.print(" ");
9487 pw.print("oom: max="); pw.print(r.maxAdj);
9488 pw.print(" hidden="); pw.print(r.hiddenAdj);
9489 pw.print(" curRaw="); pw.print(r.curRawAdj);
9490 pw.print(" setRaw="); pw.print(r.setRawAdj);
9491 pw.print(" cur="); pw.print(r.curAdj);
9492 pw.print(" set="); pw.println(r.setAdj);
9493 pw.print(prefix);
9494 pw.print(" ");
9495 pw.print("keeping="); pw.print(r.keeping);
9496 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009497 pw.print(" empty="); pw.print(r.empty);
9498 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009499
9500 if (!r.keeping) {
9501 if (r.lastWakeTime != 0) {
9502 long wtime;
9503 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9504 synchronized (stats) {
9505 wtime = stats.getProcessWakeTime(r.info.uid,
9506 r.pid, curRealtime);
9507 }
9508 long timeUsed = wtime - r.lastWakeTime;
9509 pw.print(prefix);
9510 pw.print(" ");
9511 pw.print("keep awake over ");
9512 TimeUtils.formatDuration(realtimeSince, pw);
9513 pw.print(" used ");
9514 TimeUtils.formatDuration(timeUsed, pw);
9515 pw.print(" (");
9516 pw.print((timeUsed*100)/realtimeSince);
9517 pw.println("%)");
9518 }
9519 if (r.lastCpuTime != 0) {
9520 long timeUsed = r.curCpuTime - r.lastCpuTime;
9521 pw.print(prefix);
9522 pw.print(" ");
9523 pw.print("run cpu over ");
9524 TimeUtils.formatDuration(uptimeSince, pw);
9525 pw.print(" used ");
9526 TimeUtils.formatDuration(timeUsed, pw);
9527 pw.print(" (");
9528 pw.print((timeUsed*100)/uptimeSince);
9529 pw.println("%)");
9530 }
9531 }
9532 }
9533 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009534 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009535 }
9536
Dianne Hackbornb437e092011-08-05 17:50:29 -07009537 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009538 ArrayList<ProcessRecord> procs;
9539 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009540 if (args != null && args.length > start
9541 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009542 procs = new ArrayList<ProcessRecord>();
9543 int pid = -1;
9544 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009545 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009546 } catch (NumberFormatException e) {
9547
9548 }
9549 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9550 ProcessRecord proc = mLruProcesses.get(i);
9551 if (proc.pid == pid) {
9552 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009553 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009554 procs.add(proc);
9555 }
9556 }
9557 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009558 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009559 return null;
9560 }
9561 } else {
9562 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9563 }
9564 }
9565 return procs;
9566 }
9567
9568 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9569 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009570 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009571 if (procs == null) {
9572 return;
9573 }
9574
9575 long uptime = SystemClock.uptimeMillis();
9576 long realtime = SystemClock.elapsedRealtime();
9577 pw.println("Applications Graphics Acceleration Info:");
9578 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9579
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009580 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9581 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009582 if (r.thread != null) {
9583 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9584 pw.flush();
9585 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009586 TransferPipe tp = new TransferPipe();
9587 try {
9588 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9589 tp.go(fd);
9590 } finally {
9591 tp.kill();
9592 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009593 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009594 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009595 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009596 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009597 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009598 pw.flush();
9599 }
9600 }
9601 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009602 }
9603
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009604 final static class MemItem {
9605 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009606 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009607 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009608 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009609 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009610
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009611 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009612 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009613 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009614 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009615 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009616 }
9617 }
9618
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009619 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -07009620 boolean sort) {
9621 if (sort) {
9622 Collections.sort(items, new Comparator<MemItem>() {
9623 @Override
9624 public int compare(MemItem lhs, MemItem rhs) {
9625 if (lhs.pss < rhs.pss) {
9626 return 1;
9627 } else if (lhs.pss > rhs.pss) {
9628 return -1;
9629 }
9630 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009631 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009632 });
9633 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009634
9635 for (int i=0; i<items.size(); i++) {
9636 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009637 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009638 if (mi.subitems != null) {
9639 dumpMemItems(pw, prefix + " ", mi.subitems, true);
9640 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009641 }
9642 }
9643
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009644 // These are in KB.
9645 static final long[] DUMP_MEM_BUCKETS = new long[] {
9646 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
9647 120*1024, 160*1024, 200*1024,
9648 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
9649 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
9650 };
9651
Dianne Hackborn672342c2011-11-29 11:29:02 -08009652 static final void appendMemBucket(StringBuilder out, long memKB, String label,
9653 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009654 int start = label.lastIndexOf('.');
9655 if (start >= 0) start++;
9656 else start = 0;
9657 int end = label.length();
9658 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
9659 if (DUMP_MEM_BUCKETS[i] >= memKB) {
9660 long bucket = DUMP_MEM_BUCKETS[i]/1024;
9661 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009662 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009663 out.append(label, start, end);
9664 return;
9665 }
9666 }
9667 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08009668 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009669 out.append(label, start, end);
9670 }
9671
9672 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
9673 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
9674 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
9675 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
9676 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
9677 };
9678 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
9679 "System", "Persistent", "Foreground",
9680 "Visible", "Perceptible", "Heavy Weight",
9681 "Backup", "A Services", "Home", "Previous",
9682 "B Services", "Background"
9683 };
9684
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009685 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009686 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -08009687 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009688 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009689 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009690
9691 int opti = 0;
9692 while (opti < args.length) {
9693 String opt = args[opti];
9694 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
9695 break;
9696 }
9697 opti++;
9698 if ("-a".equals(opt)) {
9699 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009700 } else if ("--oom".equals(opt)) {
9701 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009702 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009703 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009704 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009705 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -07009706 pw.println("If [process] is specified it can be the name or ");
9707 pw.println("pid of a specific process to dump.");
9708 return;
9709 } else {
9710 pw.println("Unknown argument: " + opt + "; use -h for help");
9711 }
9712 }
9713
9714 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009715 if (procs == null) {
9716 return;
9717 }
9718
Dianne Hackborn6447ca32009-04-07 19:50:08 -07009719 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009720 long uptime = SystemClock.uptimeMillis();
9721 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -07009722
9723 if (procs.size() == 1 || isCheckinRequest) {
9724 dumpAll = true;
9725 }
9726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009727 if (isCheckinRequest) {
9728 // short checkin version
9729 pw.println(uptime + "," + realtime);
9730 pw.flush();
9731 } else {
9732 pw.println("Applications Memory Usage (kB):");
9733 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9734 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009735
Dianne Hackbornb437e092011-08-05 17:50:29 -07009736 String[] innerArgs = new String[args.length-opti];
9737 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
9738
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009739 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
9740 long nativePss=0, dalvikPss=0, otherPss=0;
9741 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
9742
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009743 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
9744 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
9745 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -07009746
9747 long totalPss = 0;
9748
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009749 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9750 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009751 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009752 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009753 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
9754 pw.flush();
9755 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009756 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -07009757 if (dumpAll) {
9758 try {
9759 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
9760 } catch (RemoteException e) {
9761 if (!isCheckinRequest) {
9762 pw.println("Got RemoteException!");
9763 pw.flush();
9764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009765 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009766 } else {
9767 mi = new Debug.MemoryInfo();
9768 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009769 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009770
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009771 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009772 long myTotalPss = mi.getTotalPss();
9773 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009774 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009775 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009776 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009777
9778 nativePss += mi.nativePss;
9779 dalvikPss += mi.dalvikPss;
9780 otherPss += mi.otherPss;
9781 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
9782 long mem = mi.getOtherPss(j);
9783 miscPss[j] += mem;
9784 otherPss -= mem;
9785 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009786
9787 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009788 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
9789 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009790 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009791 if (oomProcs[oomIndex] == null) {
9792 oomProcs[oomIndex] = new ArrayList<MemItem>();
9793 }
9794 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009795 break;
9796 }
9797 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009799 }
9800 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009801
9802 if (!isCheckinRequest && procs.size() > 1) {
9803 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
9804
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009805 catMems.add(new MemItem("Native", "Native", nativePss, -1));
9806 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
9807 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009808 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009809 String label = Debug.MemoryInfo.getOtherLabel(j);
9810 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009811 }
9812
Dianne Hackbornb437e092011-08-05 17:50:29 -07009813 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
9814 for (int j=0; j<oomPss.length; j++) {
9815 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009816 String label = DUMP_MEM_OOM_LABEL[j];
9817 MemItem item = new MemItem(label, label, oomPss[j],
9818 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -07009819 item.subitems = oomProcs[j];
9820 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009821 }
9822 }
9823
Dianne Hackborn672342c2011-11-29 11:29:02 -08009824 if (outTag != null || outStack != null) {
9825 if (outTag != null) {
9826 appendMemBucket(outTag, totalPss, "total", false);
9827 }
9828 if (outStack != null) {
9829 appendMemBucket(outStack, totalPss, "total", true);
9830 }
9831 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009832 for (int i=0; i<oomMems.size(); i++) {
9833 MemItem miCat = oomMems.get(i);
9834 if (miCat.subitems == null || miCat.subitems.size() < 1) {
9835 continue;
9836 }
9837 if (miCat.id < ProcessList.SERVICE_ADJ
9838 || miCat.id == ProcessList.HOME_APP_ADJ
9839 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009840 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9841 outTag.append(" / ");
9842 }
9843 if (outStack != null) {
9844 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9845 if (firstLine) {
9846 outStack.append(":");
9847 firstLine = false;
9848 }
9849 outStack.append("\n\t at ");
9850 } else {
9851 outStack.append("$");
9852 }
9853 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009854 for (int j=0; j<miCat.subitems.size(); j++) {
9855 MemItem mi = miCat.subitems.get(j);
9856 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009857 if (outTag != null) {
9858 outTag.append(" ");
9859 }
9860 if (outStack != null) {
9861 outStack.append("$");
9862 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009863 }
Dianne Hackborn672342c2011-11-29 11:29:02 -08009864 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
9865 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
9866 }
9867 if (outStack != null) {
9868 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
9869 }
9870 }
9871 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
9872 outStack.append("(");
9873 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
9874 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
9875 outStack.append(DUMP_MEM_OOM_LABEL[k]);
9876 outStack.append(":");
9877 outStack.append(DUMP_MEM_OOM_ADJ[k]);
9878 }
9879 }
9880 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009881 }
9882 }
9883 }
9884 }
9885
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009886 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009887 pw.println();
9888 pw.println("Total PSS by process:");
9889 dumpMemItems(pw, " ", procMems, true);
9890 pw.println();
9891 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009892 pw.println("Total PSS by OOM adjustment:");
9893 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08009894 if (!oomOnly) {
9895 PrintWriter out = categoryPw != null ? categoryPw : pw;
9896 out.println();
9897 out.println("Total PSS by category:");
9898 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07009899 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07009900 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08009901 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009902 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009903 }
9904
9905 /**
9906 * Searches array of arguments for the specified string
9907 * @param args array of argument strings
9908 * @param value value to search for
9909 * @return true if the value is contained in the array
9910 */
9911 private static boolean scanArgs(String[] args, String value) {
9912 if (args != null) {
9913 for (String arg : args) {
9914 if (value.equals(arg)) {
9915 return true;
9916 }
9917 }
9918 }
9919 return false;
9920 }
9921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009922 private final void killServicesLocked(ProcessRecord app,
9923 boolean allowRestart) {
9924 // Report disconnected services.
9925 if (false) {
9926 // XXX we are letting the client link to the service for
9927 // death notifications.
9928 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009929 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009930 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009931 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009932 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009933 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009934 = r.connections.values().iterator();
9935 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009936 ArrayList<ConnectionRecord> cl = jt.next();
9937 for (int i=0; i<cl.size(); i++) {
9938 ConnectionRecord c = cl.get(i);
9939 if (c.binding.client != app) {
9940 try {
9941 //c.conn.connected(r.className, null);
9942 } catch (Exception e) {
9943 // todo: this should be asynchronous!
9944 Slog.w(TAG, "Exception thrown disconnected servce "
9945 + r.shortName
9946 + " from app " + app.processName, e);
9947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009948 }
9949 }
9950 }
9951 }
9952 }
9953 }
9954 }
9955
9956 // Clean up any connections this application has to other services.
9957 if (app.connections.size() > 0) {
9958 Iterator<ConnectionRecord> it = app.connections.iterator();
9959 while (it.hasNext()) {
9960 ConnectionRecord r = it.next();
9961 removeConnectionLocked(r, app, null);
9962 }
9963 }
9964 app.connections.clear();
9965
9966 if (app.services.size() != 0) {
9967 // Any services running in the application need to be placed
9968 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07009969 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009970 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07009971 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009972 synchronized (sr.stats.getBatteryStats()) {
9973 sr.stats.stopLaunchedLocked();
9974 }
9975 sr.app = null;
9976 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009977 if (mStoppingServices.remove(sr)) {
9978 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
9979 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07009980
9981 boolean hasClients = sr.bindings.size() > 0;
9982 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009983 Iterator<IntentBindRecord> bindings
9984 = sr.bindings.values().iterator();
9985 while (bindings.hasNext()) {
9986 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -08009987 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009988 + ": shouldUnbind=" + b.hasBound);
9989 b.binder = null;
9990 b.requested = b.received = b.hasBound = false;
9991 }
9992 }
9993
Dianne Hackborn070783f2010-12-29 16:46:28 -08009994 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
9995 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08009996 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009997 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -08009998 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009999 sr.crashCount, sr.shortName, app.pid);
10000 bringDownServiceLocked(sr, true);
10001 } else if (!allowRestart) {
10002 bringDownServiceLocked(sr, true);
10003 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010004 boolean canceled = scheduleServiceRestartLocked(sr, true);
10005
10006 // Should the service remain running? Note that in the
10007 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010008 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010009 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10010 if (sr.pendingStarts.size() == 0) {
10011 sr.startRequested = false;
10012 if (!hasClients) {
10013 // Whoops, no reason to restart!
10014 bringDownServiceLocked(sr, true);
10015 }
10016 }
10017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010018 }
10019 }
10020
10021 if (!allowRestart) {
10022 app.services.clear();
10023 }
10024 }
10025
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010026 // Make sure we have no more records on the stopping list.
10027 int i = mStoppingServices.size();
10028 while (i > 0) {
10029 i--;
10030 ServiceRecord sr = mStoppingServices.get(i);
10031 if (sr.app == app) {
10032 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010033 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010034 }
10035 }
10036
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010037 app.executingServices.clear();
10038 }
10039
10040 private final void removeDyingProviderLocked(ProcessRecord proc,
10041 ContentProviderRecord cpr) {
10042 synchronized (cpr) {
10043 cpr.launchingApp = null;
10044 cpr.notifyAll();
10045 }
10046
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010047 mProvidersByClass.remove(cpr.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010048 String names[] = cpr.info.authority.split(";");
10049 for (int j = 0; j < names.length; j++) {
10050 mProvidersByName.remove(names[j]);
10051 }
10052
10053 Iterator<ProcessRecord> cit = cpr.clients.iterator();
10054 while (cit.hasNext()) {
10055 ProcessRecord capp = cit.next();
10056 if (!capp.persistent && capp.thread != null
10057 && capp.pid != 0
10058 && capp.pid != MY_PID) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070010059 Slog.i(TAG, "Kill " + capp.processName
10060 + " (pid " + capp.pid + "): provider " + cpr.info.name
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010061 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackborn8633e682010-04-22 16:03:41 -070010062 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010063 capp.processName, capp.setAdj, "dying provider "
10064 + cpr.name.toShortString());
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010065 Process.killProcessQuiet(capp.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010066 }
10067 }
10068
10069 mLaunchingProviders.remove(cpr);
10070 }
10071
10072 /**
10073 * Main code for cleaning up a process when it has gone away. This is
10074 * called both as a result of the process dying, or directly when stopping
10075 * a process when running in single process mode.
10076 */
10077 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010078 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010079 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010080 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010081 }
10082
Dianne Hackborn36124872009-10-08 16:22:03 -070010083 mProcessesToGc.remove(app);
10084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010085 // Dismiss any open dialogs.
10086 if (app.crashDialog != null) {
10087 app.crashDialog.dismiss();
10088 app.crashDialog = null;
10089 }
10090 if (app.anrDialog != null) {
10091 app.anrDialog.dismiss();
10092 app.anrDialog = null;
10093 }
10094 if (app.waitDialog != null) {
10095 app.waitDialog.dismiss();
10096 app.waitDialog = null;
10097 }
10098
10099 app.crashing = false;
10100 app.notResponding = false;
10101
10102 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010103 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010104 app.thread = null;
10105 app.forcingToForeground = null;
10106 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010107 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010108 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010109 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010110
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010111 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010112
10113 boolean restart = false;
10114
10115 int NL = mLaunchingProviders.size();
10116
10117 // Remove published content providers.
10118 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010119 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010120 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010121 ContentProviderRecord cpr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010122 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010123 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010124
10125 // See if someone is waiting for this provider... in which
10126 // case we don't remove it, but just let it restart.
10127 int i = 0;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010128 if (!app.bad && allowRestart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010129 for (; i<NL; i++) {
10130 if (mLaunchingProviders.get(i) == cpr) {
10131 restart = true;
10132 break;
10133 }
10134 }
10135 } else {
10136 i = NL;
10137 }
10138
10139 if (i >= NL) {
10140 removeDyingProviderLocked(app, cpr);
10141 NL = mLaunchingProviders.size();
10142 }
10143 }
10144 app.pubProviders.clear();
10145 }
10146
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010147 // Take care of any launching providers waiting for this process.
10148 if (checkAppInLaunchingProvidersLocked(app, false)) {
10149 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010150 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010152 // Unregister from connected content providers.
10153 if (!app.conProviders.isEmpty()) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -070010154 Iterator it = app.conProviders.keySet().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010155 while (it.hasNext()) {
10156 ContentProviderRecord cpr = (ContentProviderRecord)it.next();
10157 cpr.clients.remove(app);
10158 }
10159 app.conProviders.clear();
10160 }
10161
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010162 // At this point there may be remaining entries in mLaunchingProviders
10163 // where we were the only one waiting, so they are no longer of use.
10164 // Look for these and clean up if found.
10165 // XXX Commented out for now. Trying to figure out a way to reproduce
10166 // the actual situation to identify what is actually going on.
10167 if (false) {
10168 for (int i=0; i<NL; i++) {
10169 ContentProviderRecord cpr = (ContentProviderRecord)
10170 mLaunchingProviders.get(i);
10171 if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
10172 synchronized (cpr) {
10173 cpr.launchingApp = null;
10174 cpr.notifyAll();
10175 }
10176 }
10177 }
10178 }
10179
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010180 skipCurrentReceiverLocked(app);
10181
10182 // Unregister any receivers.
10183 if (app.receivers.size() > 0) {
10184 Iterator<ReceiverList> it = app.receivers.iterator();
10185 while (it.hasNext()) {
10186 removeReceiverLocked(it.next());
10187 }
10188 app.receivers.clear();
10189 }
10190
Christopher Tate181fafa2009-05-14 11:12:14 -070010191 // If the app is undergoing backup, tell the backup manager about it
10192 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010193 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010194 try {
10195 IBackupManager bm = IBackupManager.Stub.asInterface(
10196 ServiceManager.getService(Context.BACKUP_SERVICE));
10197 bm.agentDisconnected(app.info.packageName);
10198 } catch (RemoteException e) {
10199 // can't happen; backup manager is local
10200 }
10201 }
10202
Jeff Sharkey287bd832011-05-28 19:36:26 -070010203 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010204
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010205 // If the caller is restarting this app, then leave it in its
10206 // current lists and let the caller take care of it.
10207 if (restarting) {
10208 return;
10209 }
10210
10211 if (!app.persistent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010212 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010213 "Removing non-persistent process during cleanup: " + app);
10214 mProcessNames.remove(app.processName, app.info.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010215 if (mHeavyWeightProcess == app) {
10216 mHeavyWeightProcess = null;
10217 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010219 } else if (!app.removed) {
10220 // This app is persistent, so we need to keep its record around.
10221 // If it is not already on the pending app list, add it there
10222 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010223 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10224 mPersistentStartingProcesses.add(app);
10225 restart = true;
10226 }
10227 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010228 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10229 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010230 mProcessesOnHold.remove(app);
10231
The Android Open Source Project4df24232009-03-05 14:34:35 -080010232 if (app == mHomeProcess) {
10233 mHomeProcess = null;
10234 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010235 if (app == mPreviousProcess) {
10236 mPreviousProcess = null;
10237 }
10238
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010239 if (restart) {
10240 // We have components that still need to be running in the
10241 // process, so re-launch it.
10242 mProcessNames.put(app.processName, app.info.uid, app);
10243 startProcessLocked(app, "restart", app.processName);
10244 } else if (app.pid > 0 && app.pid != MY_PID) {
10245 // Goodbye!
10246 synchronized (mPidsSelfLocked) {
10247 mPidsSelfLocked.remove(app.pid);
10248 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10249 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010250 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010251 }
10252 }
10253
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010254 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10255 // Look through the content providers we are waiting to have launched,
10256 // and if any run in this process then either schedule a restart of
10257 // the process or kill the client waiting for it if this process has
10258 // gone bad.
10259 int NL = mLaunchingProviders.size();
10260 boolean restart = false;
10261 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010262 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010263 if (cpr.launchingApp == app) {
10264 if (!alwaysBad && !app.bad) {
10265 restart = true;
10266 } else {
10267 removeDyingProviderLocked(app, cpr);
10268 NL = mLaunchingProviders.size();
10269 }
10270 }
10271 }
10272 return restart;
10273 }
10274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010275 // =========================================================
10276 // SERVICES
10277 // =========================================================
10278
10279 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10280 ActivityManager.RunningServiceInfo info =
10281 new ActivityManager.RunningServiceInfo();
10282 info.service = r.name;
10283 if (r.app != null) {
10284 info.pid = r.app.pid;
10285 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010286 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010287 info.process = r.processName;
10288 info.foreground = r.isForeground;
10289 info.activeSince = r.createTime;
10290 info.started = r.startRequested;
10291 info.clientCount = r.connections.size();
10292 info.crashCount = r.crashCount;
10293 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010294 if (r.isForeground) {
10295 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10296 }
10297 if (r.startRequested) {
10298 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10299 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010300 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010301 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10302 }
10303 if (r.app != null && r.app.persistent) {
10304 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
10305 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010306
10307 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
10308 for (int i=0; i<connl.size(); i++) {
10309 ConnectionRecord conn = connl.get(i);
10310 if (conn.clientLabel != 0) {
10311 info.clientPackage = conn.binding.client.info.packageName;
10312 info.clientLabel = conn.clientLabel;
10313 return info;
10314 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010315 }
10316 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010317 return info;
10318 }
10319
10320 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10321 int flags) {
10322 synchronized (this) {
10323 ArrayList<ActivityManager.RunningServiceInfo> res
10324 = new ArrayList<ActivityManager.RunningServiceInfo>();
10325
10326 if (mServices.size() > 0) {
10327 Iterator<ServiceRecord> it = mServices.values().iterator();
10328 while (it.hasNext() && res.size() < maxNum) {
10329 res.add(makeRunningServiceInfoLocked(it.next()));
10330 }
10331 }
10332
10333 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
10334 ServiceRecord r = mRestartingServices.get(i);
10335 ActivityManager.RunningServiceInfo info =
10336 makeRunningServiceInfoLocked(r);
10337 info.restarting = r.nextRestartTime;
10338 res.add(info);
10339 }
10340
10341 return res;
10342 }
10343 }
10344
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010345 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
10346 synchronized (this) {
10347 ServiceRecord r = mServices.get(name);
10348 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010349 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
10350 for (int i=0; i<conn.size(); i++) {
10351 if (conn.get(i).clientIntent != null) {
10352 return conn.get(i).clientIntent;
10353 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010354 }
10355 }
10356 }
10357 }
10358 return null;
10359 }
10360
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010361 private final ServiceRecord findServiceLocked(ComponentName name,
10362 IBinder token) {
10363 ServiceRecord r = mServices.get(name);
10364 return r == token ? r : null;
10365 }
10366
10367 private final class ServiceLookupResult {
10368 final ServiceRecord record;
10369 final String permission;
10370
10371 ServiceLookupResult(ServiceRecord _record, String _permission) {
10372 record = _record;
10373 permission = _permission;
10374 }
10375 };
10376
10377 private ServiceLookupResult findServiceLocked(Intent service,
10378 String resolvedType) {
10379 ServiceRecord r = null;
10380 if (service.getComponent() != null) {
10381 r = mServices.get(service.getComponent());
10382 }
10383 if (r == null) {
10384 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10385 r = mServicesByIntent.get(filter);
10386 }
10387
10388 if (r == null) {
10389 try {
10390 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010391 AppGlobals.getPackageManager().resolveService(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010392 service, resolvedType, 0);
10393 ServiceInfo sInfo =
10394 rInfo != null ? rInfo.serviceInfo : null;
10395 if (sInfo == null) {
10396 return null;
10397 }
10398
10399 ComponentName name = new ComponentName(
10400 sInfo.applicationInfo.packageName, sInfo.name);
10401 r = mServices.get(name);
10402 } catch (RemoteException ex) {
10403 // pm is in same process, this will never happen.
10404 }
10405 }
10406 if (r != null) {
10407 int callingPid = Binder.getCallingPid();
10408 int callingUid = Binder.getCallingUid();
10409 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010410 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010411 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010412 if (!r.exported) {
10413 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10414 + " from pid=" + callingPid
10415 + ", uid=" + callingUid
10416 + " that is not exported from uid " + r.appInfo.uid);
10417 return new ServiceLookupResult(null, "not exported from uid "
10418 + r.appInfo.uid);
10419 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010420 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010421 + " from pid=" + callingPid
10422 + ", uid=" + callingUid
10423 + " requires " + r.permission);
10424 return new ServiceLookupResult(null, r.permission);
10425 }
10426 return new ServiceLookupResult(r, null);
10427 }
10428 return null;
10429 }
10430
10431 private class ServiceRestarter implements Runnable {
10432 private ServiceRecord mService;
10433
10434 void setService(ServiceRecord service) {
10435 mService = service;
10436 }
10437
10438 public void run() {
10439 synchronized(ActivityManagerService.this) {
10440 performServiceRestartLocked(mService);
10441 }
10442 }
10443 }
10444
10445 private ServiceLookupResult retrieveServiceLocked(Intent service,
10446 String resolvedType, int callingPid, int callingUid) {
10447 ServiceRecord r = null;
10448 if (service.getComponent() != null) {
10449 r = mServices.get(service.getComponent());
10450 }
10451 Intent.FilterComparison filter = new Intent.FilterComparison(service);
10452 r = mServicesByIntent.get(filter);
10453 if (r == null) {
10454 try {
10455 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070010456 AppGlobals.getPackageManager().resolveService(
Dianne Hackborn1655be42009-05-08 14:29:01 -070010457 service, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010458 ServiceInfo sInfo =
10459 rInfo != null ? rInfo.serviceInfo : null;
10460 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010461 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010462 ": not found");
10463 return null;
10464 }
10465
10466 ComponentName name = new ComponentName(
10467 sInfo.applicationInfo.packageName, sInfo.name);
10468 r = mServices.get(name);
10469 if (r == null) {
10470 filter = new Intent.FilterComparison(service.cloneFilter());
10471 ServiceRestarter res = new ServiceRestarter();
10472 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10473 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10474 synchronized (stats) {
10475 ss = stats.getServiceStatsLocked(
10476 sInfo.applicationInfo.uid, sInfo.packageName,
10477 sInfo.name);
10478 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080010479 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010480 res.setService(r);
10481 mServices.put(name, r);
10482 mServicesByIntent.put(filter, r);
10483
10484 // Make sure this component isn't in the pending list.
10485 int N = mPendingServices.size();
10486 for (int i=0; i<N; i++) {
10487 ServiceRecord pr = mPendingServices.get(i);
10488 if (pr.name.equals(name)) {
10489 mPendingServices.remove(i);
10490 i--;
10491 N--;
10492 }
10493 }
10494 }
10495 } catch (RemoteException ex) {
10496 // pm is in same process, this will never happen.
10497 }
10498 }
10499 if (r != null) {
10500 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010501 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010502 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010503 if (!r.exported) {
10504 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
10505 + " from pid=" + callingPid
10506 + ", uid=" + callingUid
10507 + " that is not exported from uid " + r.appInfo.uid);
10508 return new ServiceLookupResult(null, "not exported from uid "
10509 + r.appInfo.uid);
10510 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080010511 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080010512 + " from pid=" + callingPid
10513 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010514 + " requires " + r.permission);
10515 return new ServiceLookupResult(null, r.permission);
10516 }
10517 return new ServiceLookupResult(r, null);
10518 }
10519 return null;
10520 }
10521
Dianne Hackborn287952c2010-09-22 22:34:31 -070010522 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
10523 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
10524 + why + " of " + r + " in app " + r.app);
10525 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
10526 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010527 long now = SystemClock.uptimeMillis();
10528 if (r.executeNesting == 0 && r.app != null) {
10529 if (r.app.executingServices.size() == 0) {
10530 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
10531 msg.obj = r.app;
10532 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
10533 }
10534 r.app.executingServices.add(r);
10535 }
10536 r.executeNesting++;
10537 r.executingStart = now;
10538 }
10539
10540 private final void sendServiceArgsLocked(ServiceRecord r,
10541 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010542 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010543 if (N == 0) {
10544 return;
10545 }
10546
Dianne Hackborn39792d22010-08-19 18:01:52 -070010547 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010548 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010549 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010550 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
10551 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010552 if (si.intent == null && N > 1) {
10553 // If somehow we got a dummy null intent in the middle,
10554 // then skip it. DO NOT skip a null intent when it is
10555 // the only one in the list -- this is to support the
10556 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010557 continue;
10558 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070010559 si.deliveredTime = SystemClock.uptimeMillis();
10560 r.deliveredStarts.add(si);
10561 si.deliveryCount++;
Dianne Hackborn3a28f222011-03-01 12:25:54 -080010562 if (si.targetPermissionUid >= 0 && si.intent != null) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070010563 grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
Dianne Hackborn7e269642010-08-25 19:50:20 -070010564 r.packageName, si.intent, si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070010565 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010566 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010567 if (!oomAdjusted) {
10568 oomAdjusted = true;
10569 updateOomAdjLocked(r.app);
10570 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010571 int flags = 0;
10572 if (si.deliveryCount > 0) {
10573 flags |= Service.START_FLAG_RETRY;
10574 }
10575 if (si.doneExecutingCount > 0) {
10576 flags |= Service.START_FLAG_REDELIVERY;
10577 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010578 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010579 } catch (RemoteException e) {
10580 // Remote process gone... we'll let the normal cleanup take
10581 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010582 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010583 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010584 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010585 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 break;
10587 }
10588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010589 }
10590
10591 private final boolean requestServiceBindingLocked(ServiceRecord r,
10592 IntentBindRecord i, boolean rebind) {
10593 if (r.app == null || r.app.thread == null) {
10594 // If service is not currently running, can't yet bind.
10595 return false;
10596 }
10597 if ((!i.requested || rebind) && i.apps.size() > 0) {
10598 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010599 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010600 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
10601 if (!rebind) {
10602 i.requested = true;
10603 }
10604 i.hasBound = true;
10605 i.doRebind = false;
10606 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010607 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010608 return false;
10609 }
10610 }
10611 return true;
10612 }
10613
10614 private final void requestServiceBindingsLocked(ServiceRecord r) {
10615 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
10616 while (bindings.hasNext()) {
10617 IntentBindRecord i = bindings.next();
10618 if (!requestServiceBindingLocked(r, i, false)) {
10619 break;
10620 }
10621 }
10622 }
10623
10624 private final void realStartServiceLocked(ServiceRecord r,
10625 ProcessRecord app) throws RemoteException {
10626 if (app.thread == null) {
10627 throw new RemoteException();
10628 }
10629
10630 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070010631 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010632
10633 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010634 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010635 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010636
10637 boolean created = false;
10638 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010639 mStringBuilder.setLength(0);
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010640 r.intent.getIntent().toShortString(mStringBuilder, true, false, true);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010641 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010642 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070010643 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010644 synchronized (r.stats.getBatteryStats()) {
10645 r.stats.startLaunchedLocked();
10646 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070010647 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010648 app.thread.scheduleCreateService(r, r.serviceInfo,
10649 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010650 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010651 created = true;
10652 } finally {
10653 if (!created) {
10654 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010655 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010656 }
10657 }
10658
10659 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010660
10661 // If the service is in the started state, and there are no
10662 // pending arguments, then fake up one so its onStartCommand() will
10663 // be called.
10664 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070010665 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
10666 null, -1));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010667 }
10668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010669 sendServiceArgsLocked(r, true);
10670 }
10671
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010672 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
10673 boolean allowCancel) {
10674 boolean canceled = false;
10675
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010676 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010677 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070010678 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010679
Dianne Hackborn070783f2010-12-29 16:46:28 -080010680 if ((r.serviceInfo.applicationInfo.flags
10681 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10682 minDuration /= 4;
10683 }
10684
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010685 // Any delivered but not yet finished starts should be put back
10686 // on the pending list.
10687 final int N = r.deliveredStarts.size();
10688 if (N > 0) {
10689 for (int i=N-1; i>=0; i--) {
10690 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070010691 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010692 if (si.intent == null) {
10693 // We'll generate this again if needed.
10694 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
10695 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
10696 r.pendingStarts.add(0, si);
10697 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
10698 dur *= 2;
10699 if (minDuration < dur) minDuration = dur;
10700 if (resetTime < dur) resetTime = dur;
10701 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010702 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010703 + r.name);
10704 canceled = true;
10705 }
10706 }
10707 r.deliveredStarts.clear();
10708 }
10709
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010710 r.totalRestartCount++;
10711 if (r.restartDelay == 0) {
10712 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010713 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010714 } else {
10715 // If it has been a "reasonably long time" since the service
10716 // was started, then reset our restart duration back to
10717 // the beginning, so we don't infinitely increase the duration
10718 // on a service that just occasionally gets killed (which is
10719 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010720 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010721 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010722 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010723 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080010724 if ((r.serviceInfo.applicationInfo.flags
10725 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
10726 // Services in peristent processes will restart much more
10727 // quickly, since they are pretty important. (Think SystemUI).
10728 r.restartDelay += minDuration/2;
10729 } else {
10730 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
10731 if (r.restartDelay < minDuration) {
10732 r.restartDelay = minDuration;
10733 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010734 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010735 }
10736 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010737
10738 r.nextRestartTime = now + r.restartDelay;
10739
10740 // Make sure that we don't end up restarting a bunch of services
10741 // all at the same time.
10742 boolean repeat;
10743 do {
10744 repeat = false;
10745 for (int i=mRestartingServices.size()-1; i>=0; i--) {
10746 ServiceRecord r2 = mRestartingServices.get(i);
10747 if (r2 != r && r.nextRestartTime
10748 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
10749 && r.nextRestartTime
10750 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
10751 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
10752 r.restartDelay = r.nextRestartTime - now;
10753 repeat = true;
10754 break;
10755 }
10756 }
10757 } while (repeat);
10758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010759 if (!mRestartingServices.contains(r)) {
10760 mRestartingServices.add(r);
10761 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010762
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010763 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010765 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070010766 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010767 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080010768 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010769 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080010770 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010771 r.shortName, r.restartDelay);
10772
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010773 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010774 }
10775
10776 final void performServiceRestartLocked(ServiceRecord r) {
10777 if (!mRestartingServices.contains(r)) {
10778 return;
10779 }
10780 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
10781 }
10782
10783 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
10784 if (r.restartDelay == 0) {
10785 return false;
10786 }
10787 r.resetRestartCounter();
10788 mRestartingServices.remove(r);
10789 mHandler.removeCallbacks(r.restarter);
10790 return true;
10791 }
10792
10793 private final boolean bringUpServiceLocked(ServiceRecord r,
10794 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010795 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010796 //r.dump(" ");
10797
Dianne Hackborn36124872009-10-08 16:22:03 -070010798 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010799 sendServiceArgsLocked(r, false);
10800 return true;
10801 }
10802
10803 if (!whileRestarting && r.restartDelay > 0) {
10804 // If waiting for a restart, then do nothing.
10805 return true;
10806 }
10807
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010808 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010809
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010810 // We are now bringing the service up, so no longer in the
10811 // restarting state.
10812 mRestartingServices.remove(r);
10813
Dianne Hackborne7f97212011-02-24 14:40:20 -080010814 // Service is now being launched, its package can't be stopped.
10815 try {
10816 AppGlobals.getPackageManager().setPackageStoppedState(
10817 r.packageName, false);
10818 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010819 } catch (IllegalArgumentException e) {
10820 Slog.w(TAG, "Failed trying to unstop package "
10821 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010822 }
10823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010824 final String appName = r.processName;
10825 ProcessRecord app = getProcessRecordLocked(appName, r.appInfo.uid);
10826 if (app != null && app.thread != null) {
10827 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070010828 app.addPackage(r.appInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010829 realStartServiceLocked(r, app);
10830 return true;
10831 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010832 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010833 }
10834
10835 // If a dead object exception was thrown -- fall through to
10836 // restart the application.
10837 }
10838
Dianne Hackborn36124872009-10-08 16:22:03 -070010839 // Not running -- get it started, and enqueue this service record
10840 // to be executed when the app comes up.
10841 if (startProcessLocked(appName, r.appInfo, true, intentFlags,
10842 "service", r.name, false) == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010843 Slog.w(TAG, "Unable to launch app "
Dianne Hackborn36124872009-10-08 16:22:03 -070010844 + r.appInfo.packageName + "/"
10845 + r.appInfo.uid + " for service "
10846 + r.intent.getIntent() + ": process is bad");
10847 bringDownServiceLocked(r, true);
10848 return false;
10849 }
10850
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010851 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010852 mPendingServices.add(r);
10853 }
Dianne Hackborn36124872009-10-08 16:22:03 -070010854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010855 return true;
10856 }
10857
10858 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010859 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010860 //r.dump(" ");
10861
10862 // Does it still need to run?
10863 if (!force && r.startRequested) {
10864 return;
10865 }
10866 if (r.connections.size() > 0) {
10867 if (!force) {
10868 // XXX should probably keep a count of the number of auto-create
10869 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010870 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010871 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010872 ArrayList<ConnectionRecord> cr = it.next();
10873 for (int i=0; i<cr.size(); i++) {
10874 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
10875 return;
10876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010877 }
10878 }
10879 }
10880
10881 // Report to all of the connections that the service is no longer
10882 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010883 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010884 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010885 ArrayList<ConnectionRecord> c = it.next();
10886 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010887 ConnectionRecord cr = c.get(i);
10888 // There is still a connection to the service that is
10889 // being brought down. Mark it as dead.
10890 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010891 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010892 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010893 } catch (Exception e) {
10894 Slog.w(TAG, "Failure disconnecting service " + r.name +
10895 " to connection " + c.get(i).conn.asBinder() +
10896 " (in " + c.get(i).binding.client.processName + ")", e);
10897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 }
10899 }
10900 }
10901
10902 // Tell the service that it has been unbound.
10903 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
10904 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
10905 while (it.hasNext()) {
10906 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010907 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010908 + ": hasBound=" + ibr.hasBound);
10909 if (r.app != null && r.app.thread != null && ibr.hasBound) {
10910 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010911 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010912 updateOomAdjLocked(r.app);
10913 ibr.hasBound = false;
10914 r.app.thread.scheduleUnbindService(r,
10915 ibr.intent.getIntent());
10916 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010917 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010918 + r.shortName, e);
10919 serviceDoneExecutingLocked(r, true);
10920 }
10921 }
10922 }
10923 }
10924
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010925 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010926 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010927 System.identityHashCode(r), r.shortName,
10928 (r.app != null) ? r.app.pid : -1);
10929
10930 mServices.remove(r.name);
10931 mServicesByIntent.remove(r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010932 r.totalRestartCount = 0;
10933 unscheduleServiceRestartLocked(r);
10934
10935 // Also make sure it is not on the pending list.
10936 int N = mPendingServices.size();
10937 for (int i=0; i<N; i++) {
10938 if (mPendingServices.get(i) == r) {
10939 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010940 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010941 i--;
10942 N--;
10943 }
10944 }
10945
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010946 r.cancelNotification();
10947 r.isForeground = false;
10948 r.foregroundId = 0;
10949 r.foregroundNoti = null;
10950
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010951 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070010952 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010953 r.pendingStarts.clear();
10954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010955 if (r.app != null) {
10956 synchronized (r.stats.getBatteryStats()) {
10957 r.stats.stopLaunchedLocked();
10958 }
10959 r.app.services.remove(r);
10960 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010961 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010962 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010963 mStoppingServices.add(r);
10964 updateOomAdjLocked(r.app);
10965 r.app.thread.scheduleStopService(r);
10966 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010967 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010968 + r.shortName, e);
10969 serviceDoneExecutingLocked(r, true);
10970 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010971 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010972 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010973 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010974 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010975 }
10976 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010977 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010978 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010979 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080010980
10981 if (r.bindings.size() > 0) {
10982 r.bindings.clear();
10983 }
10984
10985 if (r.restarter instanceof ServiceRestarter) {
10986 ((ServiceRestarter)r.restarter).setService(null);
10987 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010988 }
10989
10990 ComponentName startServiceLocked(IApplicationThread caller,
10991 Intent service, String resolvedType,
10992 int callingPid, int callingUid) {
10993 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010994 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010995 + " type=" + resolvedType + " args=" + service.getExtras());
10996
10997 if (caller != null) {
10998 final ProcessRecord callerApp = getRecordForAppLocked(caller);
10999 if (callerApp == null) {
11000 throw new SecurityException(
11001 "Unable to find app for caller " + caller
11002 + " (pid=" + Binder.getCallingPid()
11003 + ") when starting service " + service);
11004 }
11005 }
11006
11007 ServiceLookupResult res =
11008 retrieveServiceLocked(service, resolvedType,
11009 callingPid, callingUid);
11010 if (res == null) {
11011 return null;
11012 }
11013 if (res.record == null) {
11014 return new ComponentName("!", res.permission != null
11015 ? res.permission : "private to package");
11016 }
11017 ServiceRecord r = res.record;
Dianne Hackborn39792d22010-08-19 18:01:52 -070011018 int targetPermissionUid = checkGrantUriPermissionFromIntentLocked(
11019 callingUid, r.packageName, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011020 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011021 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011022 }
11023 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011024 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011025 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn39792d22010-08-19 18:01:52 -070011026 service, targetPermissionUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011027 r.lastActivity = SystemClock.uptimeMillis();
11028 synchronized (r.stats.getBatteryStats()) {
11029 r.stats.startRunningLocked();
11030 }
11031 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11032 return new ComponentName("!", "Service process is bad");
11033 }
11034 return r.name;
11035 }
11036 }
11037
11038 public ComponentName startService(IApplicationThread caller, Intent service,
11039 String resolvedType) {
11040 // Refuse possible leaked file descriptors
11041 if (service != null && service.hasFileDescriptors() == true) {
11042 throw new IllegalArgumentException("File descriptors passed in Intent");
11043 }
11044
11045 synchronized(this) {
11046 final int callingPid = Binder.getCallingPid();
11047 final int callingUid = Binder.getCallingUid();
11048 final long origId = Binder.clearCallingIdentity();
11049 ComponentName res = startServiceLocked(caller, service,
11050 resolvedType, callingPid, callingUid);
11051 Binder.restoreCallingIdentity(origId);
11052 return res;
11053 }
11054 }
11055
11056 ComponentName startServiceInPackage(int uid,
11057 Intent service, String resolvedType) {
11058 synchronized(this) {
11059 final long origId = Binder.clearCallingIdentity();
11060 ComponentName res = startServiceLocked(null, service,
11061 resolvedType, -1, uid);
11062 Binder.restoreCallingIdentity(origId);
11063 return res;
11064 }
11065 }
11066
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011067 private void stopServiceLocked(ServiceRecord service) {
11068 synchronized (service.stats.getBatteryStats()) {
11069 service.stats.stopRunningLocked();
11070 }
11071 service.startRequested = false;
11072 service.callStart = false;
11073 bringDownServiceLocked(service, false);
11074 }
11075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011076 public int stopService(IApplicationThread caller, Intent service,
11077 String resolvedType) {
11078 // Refuse possible leaked file descriptors
11079 if (service != null && service.hasFileDescriptors() == true) {
11080 throw new IllegalArgumentException("File descriptors passed in Intent");
11081 }
11082
11083 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011084 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011085 + " type=" + resolvedType);
11086
11087 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11088 if (caller != null && callerApp == null) {
11089 throw new SecurityException(
11090 "Unable to find app for caller " + caller
11091 + " (pid=" + Binder.getCallingPid()
11092 + ") when stopping service " + service);
11093 }
11094
11095 // If this service is active, make sure it is stopped.
11096 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11097 if (r != null) {
11098 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011099 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011100 try {
11101 stopServiceLocked(r.record);
11102 } finally {
11103 Binder.restoreCallingIdentity(origId);
11104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011105 return 1;
11106 }
11107 return -1;
11108 }
11109 }
11110
11111 return 0;
11112 }
11113
11114 public IBinder peekService(Intent service, String resolvedType) {
11115 // Refuse possible leaked file descriptors
11116 if (service != null && service.hasFileDescriptors() == true) {
11117 throw new IllegalArgumentException("File descriptors passed in Intent");
11118 }
11119
11120 IBinder ret = null;
11121
11122 synchronized(this) {
11123 ServiceLookupResult r = findServiceLocked(service, resolvedType);
11124
11125 if (r != null) {
11126 // r.record is null if findServiceLocked() failed the caller permission check
11127 if (r.record == null) {
11128 throw new SecurityException(
11129 "Permission Denial: Accessing service " + r.record.name
11130 + " from pid=" + Binder.getCallingPid()
11131 + ", uid=" + Binder.getCallingUid()
11132 + " requires " + r.permission);
11133 }
11134 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11135 if (ib != null) {
11136 ret = ib.binder;
11137 }
11138 }
11139 }
11140
11141 return ret;
11142 }
11143
11144 public boolean stopServiceToken(ComponentName className, IBinder token,
11145 int startId) {
11146 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011147 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011148 + " " + token + " startId=" + startId);
11149 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011150 if (r != null) {
11151 if (startId >= 0) {
11152 // Asked to only stop if done with all work. Note that
11153 // to avoid leaks, we will take this as dropping all
11154 // start items up to and including this one.
11155 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11156 if (si != null) {
11157 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011158 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11159 cur.removeUriPermissionsLocked();
11160 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011161 break;
11162 }
11163 }
11164 }
11165
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011166 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011167 return false;
11168 }
11169
11170 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011171 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011172 + " is last, but have " + r.deliveredStarts.size()
11173 + " remaining args");
11174 }
11175 }
11176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011177 synchronized (r.stats.getBatteryStats()) {
11178 r.stats.stopRunningLocked();
11179 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011180 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 }
11182 final long origId = Binder.clearCallingIdentity();
11183 bringDownServiceLocked(r, false);
11184 Binder.restoreCallingIdentity(origId);
11185 return true;
11186 }
11187 }
11188 return false;
11189 }
11190
11191 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011192 int id, Notification notification, boolean removeNotification) {
11193 final long origId = Binder.clearCallingIdentity();
11194 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011195 synchronized(this) {
11196 ServiceRecord r = findServiceLocked(className, token);
11197 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011198 if (id != 0) {
11199 if (notification == null) {
11200 throw new IllegalArgumentException("null notification");
11201 }
11202 if (r.foregroundId != id) {
11203 r.cancelNotification();
11204 r.foregroundId = id;
11205 }
11206 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11207 r.foregroundNoti = notification;
11208 r.isForeground = true;
11209 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011210 if (r.app != null) {
11211 updateServiceForegroundLocked(r.app, true);
11212 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011213 } else {
11214 if (r.isForeground) {
11215 r.isForeground = false;
11216 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011217 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011218 updateServiceForegroundLocked(r.app, true);
11219 }
11220 }
11221 if (removeNotification) {
11222 r.cancelNotification();
11223 r.foregroundId = 0;
11224 r.foregroundNoti = null;
11225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011226 }
11227 }
11228 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011229 } finally {
11230 Binder.restoreCallingIdentity(origId);
11231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011232 }
11233
11234 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11235 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070011236 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011237 if (sr.isForeground) {
11238 anyForeground = true;
11239 break;
11240 }
11241 }
11242 if (anyForeground != proc.foregroundServices) {
11243 proc.foregroundServices = anyForeground;
11244 if (oomAdj) {
11245 updateOomAdjLocked();
11246 }
11247 }
11248 }
11249
11250 public int bindService(IApplicationThread caller, IBinder token,
11251 Intent service, String resolvedType,
11252 IServiceConnection connection, int flags) {
11253 // Refuse possible leaked file descriptors
11254 if (service != null && service.hasFileDescriptors() == true) {
11255 throw new IllegalArgumentException("File descriptors passed in Intent");
11256 }
11257
11258 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011259 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011260 + " type=" + resolvedType + " conn=" + connection.asBinder()
11261 + " flags=0x" + Integer.toHexString(flags));
11262 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11263 if (callerApp == null) {
11264 throw new SecurityException(
11265 "Unable to find app for caller " + caller
11266 + " (pid=" + Binder.getCallingPid()
11267 + ") when binding service " + service);
11268 }
11269
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011270 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011271 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070011272 activity = mMainStack.isInStackLocked(token);
11273 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011274 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011275 return 0;
11276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011277 }
11278
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011279 int clientLabel = 0;
11280 PendingIntent clientIntent = null;
11281
11282 if (callerApp.info.uid == Process.SYSTEM_UID) {
11283 // Hacky kind of thing -- allow system stuff to tell us
11284 // what they are, so we can report this elsewhere for
11285 // others to know why certain services are running.
11286 try {
11287 clientIntent = (PendingIntent)service.getParcelableExtra(
11288 Intent.EXTRA_CLIENT_INTENT);
11289 } catch (RuntimeException e) {
11290 }
11291 if (clientIntent != null) {
11292 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
11293 if (clientLabel != 0) {
11294 // There are no useful extras in the intent, trash them.
11295 // System code calling with this stuff just needs to know
11296 // this will happen.
11297 service = service.cloneFilter();
11298 }
11299 }
11300 }
11301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011302 ServiceLookupResult res =
11303 retrieveServiceLocked(service, resolvedType,
11304 Binder.getCallingPid(), Binder.getCallingUid());
11305 if (res == null) {
11306 return 0;
11307 }
11308 if (res.record == null) {
11309 return -1;
11310 }
11311 ServiceRecord s = res.record;
11312
11313 final long origId = Binder.clearCallingIdentity();
11314
11315 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011316 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011317 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011318 }
11319
11320 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
11321 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011322 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011323
11324 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011325 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11326 if (clist == null) {
11327 clist = new ArrayList<ConnectionRecord>();
11328 s.connections.put(binder, clist);
11329 }
11330 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011331 b.connections.add(c);
11332 if (activity != null) {
11333 if (activity.connections == null) {
11334 activity.connections = new HashSet<ConnectionRecord>();
11335 }
11336 activity.connections.add(c);
11337 }
11338 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011339 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11340 b.client.hasAboveClient = true;
11341 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011342 clist = mServiceConnections.get(binder);
11343 if (clist == null) {
11344 clist = new ArrayList<ConnectionRecord>();
11345 mServiceConnections.put(binder, clist);
11346 }
11347 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011348
11349 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
11350 s.lastActivity = SystemClock.uptimeMillis();
11351 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
11352 return 0;
11353 }
11354 }
11355
11356 if (s.app != null) {
11357 // This could have made the service more important.
11358 updateOomAdjLocked(s.app);
11359 }
11360
Joe Onorato8a9b2202010-02-26 18:56:32 -080011361 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011362 + ": received=" + b.intent.received
11363 + " apps=" + b.intent.apps.size()
11364 + " doRebind=" + b.intent.doRebind);
11365
11366 if (s.app != null && b.intent.received) {
11367 // Service is already running, so we can immediately
11368 // publish the connection.
11369 try {
11370 c.conn.connected(s.name, b.intent.binder);
11371 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011372 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011373 + " to connection " + c.conn.asBinder()
11374 + " (in " + c.binding.client.processName + ")", e);
11375 }
11376
11377 // If this is the first app connected back to this binding,
11378 // and the service had previously asked to be told when
11379 // rebound, then do so.
11380 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
11381 requestServiceBindingLocked(s, b.intent, true);
11382 }
11383 } else if (!b.intent.requested) {
11384 requestServiceBindingLocked(s, b.intent, false);
11385 }
11386
11387 Binder.restoreCallingIdentity(origId);
11388 }
11389
11390 return 1;
11391 }
11392
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070011393 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011394 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011395 IBinder binder = c.conn.asBinder();
11396 AppBindRecord b = c.binding;
11397 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011398 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
11399 if (clist != null) {
11400 clist.remove(c);
11401 if (clist.size() == 0) {
11402 s.connections.remove(binder);
11403 }
11404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011405 b.connections.remove(c);
11406 if (c.activity != null && c.activity != skipAct) {
11407 if (c.activity.connections != null) {
11408 c.activity.connections.remove(c);
11409 }
11410 }
11411 if (b.client != skipApp) {
11412 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070011413 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
11414 b.client.updateHasAboveClientLocked();
11415 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011417 clist = mServiceConnections.get(binder);
11418 if (clist != null) {
11419 clist.remove(c);
11420 if (clist.size() == 0) {
11421 mServiceConnections.remove(binder);
11422 }
11423 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011424
11425 if (b.connections.size() == 0) {
11426 b.intent.apps.remove(b.client);
11427 }
11428
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011429 if (!c.serviceDead) {
11430 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
11431 + ": shouldUnbind=" + b.intent.hasBound);
11432 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
11433 && b.intent.hasBound) {
11434 try {
11435 bumpServiceExecutingLocked(s, "unbind");
11436 updateOomAdjLocked(s.app);
11437 b.intent.hasBound = false;
11438 // Assume the client doesn't want to know about a rebind;
11439 // we will deal with that later if it asks for one.
11440 b.intent.doRebind = false;
11441 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
11442 } catch (Exception e) {
11443 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
11444 serviceDoneExecutingLocked(s, true);
11445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011446 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011447
11448 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
11449 bringDownServiceLocked(s, false);
11450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011451 }
11452 }
11453
11454 public boolean unbindService(IServiceConnection connection) {
11455 synchronized (this) {
11456 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011457 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011458 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
11459 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011460 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011461 + connection.asBinder());
11462 return false;
11463 }
11464
11465 final long origId = Binder.clearCallingIdentity();
11466
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011467 while (clist.size() > 0) {
11468 ConnectionRecord r = clist.get(0);
11469 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011470
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011471 if (r.binding.service.app != null) {
11472 // This could have made the service less important.
11473 updateOomAdjLocked(r.binding.service.app);
11474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011475 }
11476
11477 Binder.restoreCallingIdentity(origId);
11478 }
11479
11480 return true;
11481 }
11482
11483 public void publishService(IBinder token, Intent intent, IBinder service) {
11484 // Refuse possible leaked file descriptors
11485 if (intent != null && intent.hasFileDescriptors() == true) {
11486 throw new IllegalArgumentException("File descriptors passed in Intent");
11487 }
11488
11489 synchronized(this) {
11490 if (!(token instanceof ServiceRecord)) {
11491 throw new IllegalArgumentException("Invalid service token");
11492 }
11493 ServiceRecord r = (ServiceRecord)token;
11494
11495 final long origId = Binder.clearCallingIdentity();
11496
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011497 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011498 + " " + intent + ": " + service);
11499 if (r != null) {
11500 Intent.FilterComparison filter
11501 = new Intent.FilterComparison(intent);
11502 IntentBindRecord b = r.bindings.get(filter);
11503 if (b != null && !b.received) {
11504 b.binder = service;
11505 b.requested = true;
11506 b.received = true;
11507 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011508 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011509 = r.connections.values().iterator();
11510 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011511 ArrayList<ConnectionRecord> clist = it.next();
11512 for (int i=0; i<clist.size(); i++) {
11513 ConnectionRecord c = clist.get(i);
11514 if (!filter.equals(c.binding.intent.intent)) {
11515 if (DEBUG_SERVICE) Slog.v(
11516 TAG, "Not publishing to: " + c);
11517 if (DEBUG_SERVICE) Slog.v(
11518 TAG, "Bound intent: " + c.binding.intent.intent);
11519 if (DEBUG_SERVICE) Slog.v(
11520 TAG, "Published intent: " + intent);
11521 continue;
11522 }
11523 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
11524 try {
11525 c.conn.connected(r.name, service);
11526 } catch (Exception e) {
11527 Slog.w(TAG, "Failure sending service " + r.name +
11528 " to connection " + c.conn.asBinder() +
11529 " (in " + c.binding.client.processName + ")", e);
11530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011531 }
11532 }
11533 }
11534 }
11535
11536 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
11537
11538 Binder.restoreCallingIdentity(origId);
11539 }
11540 }
11541 }
11542
11543 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11544 // Refuse possible leaked file descriptors
11545 if (intent != null && intent.hasFileDescriptors() == true) {
11546 throw new IllegalArgumentException("File descriptors passed in Intent");
11547 }
11548
11549 synchronized(this) {
11550 if (!(token instanceof ServiceRecord)) {
11551 throw new IllegalArgumentException("Invalid service token");
11552 }
11553 ServiceRecord r = (ServiceRecord)token;
11554
11555 final long origId = Binder.clearCallingIdentity();
11556
11557 if (r != null) {
11558 Intent.FilterComparison filter
11559 = new Intent.FilterComparison(intent);
11560 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011561 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011562 + " at " + b + ": apps="
11563 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020011564
11565 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011566 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020011567 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011568 // Applications have already bound since the last
11569 // unbind, so just rebind right here.
11570 requestServiceBindingLocked(r, b, true);
11571 } else {
11572 // Note to tell the service the next time there is
11573 // a new client.
11574 b.doRebind = true;
11575 }
11576 }
11577
Per Edelberg78f9fff2010-08-30 20:01:35 +020011578 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011579
11580 Binder.restoreCallingIdentity(origId);
11581 }
11582 }
11583 }
11584
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011585 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011586 synchronized(this) {
11587 if (!(token instanceof ServiceRecord)) {
11588 throw new IllegalArgumentException("Invalid service token");
11589 }
11590 ServiceRecord r = (ServiceRecord)token;
11591 boolean inStopping = mStoppingServices.contains(token);
11592 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011593 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011594 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011595 + " with incorrect token: given " + token
11596 + ", expected " + r);
11597 return;
11598 }
11599
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011600 if (type == 1) {
11601 // This is a call from a service start... take care of
11602 // book-keeping.
11603 r.callStart = true;
11604 switch (res) {
11605 case Service.START_STICKY_COMPATIBILITY:
11606 case Service.START_STICKY: {
11607 // We are done with the associated start arguments.
11608 r.findDeliveredStart(startId, true);
11609 // Don't stop if killed.
11610 r.stopIfKilled = false;
11611 break;
11612 }
11613 case Service.START_NOT_STICKY: {
11614 // We are done with the associated start arguments.
11615 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011616 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011617 // There is no more work, and this service
11618 // doesn't want to hang around if killed.
11619 r.stopIfKilled = true;
11620 }
11621 break;
11622 }
11623 case Service.START_REDELIVER_INTENT: {
11624 // We'll keep this item until they explicitly
11625 // call stop for it, but keep track of the fact
11626 // that it was delivered.
11627 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11628 if (si != null) {
11629 si.deliveryCount = 0;
11630 si.doneExecutingCount++;
11631 // Don't stop if killed.
11632 r.stopIfKilled = true;
11633 }
11634 break;
11635 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011636 case Service.START_TASK_REMOVED_COMPLETE: {
11637 // Special processing for onTaskRemoved(). Don't
11638 // impact normal onStartCommand() processing.
11639 r.findDeliveredStart(startId, true);
11640 break;
11641 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011642 default:
11643 throw new IllegalArgumentException(
11644 "Unknown service start result: " + res);
11645 }
11646 if (res == Service.START_STICKY_COMPATIBILITY) {
11647 r.callStart = false;
11648 }
11649 }
11650
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011651 final long origId = Binder.clearCallingIdentity();
11652 serviceDoneExecutingLocked(r, inStopping);
11653 Binder.restoreCallingIdentity(origId);
11654 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011655 Slog.w(TAG, "Done executing unknown service from pid "
11656 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011657 }
11658 }
11659 }
11660
11661 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011662 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
11663 + ": nesting=" + r.executeNesting
11664 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011665 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011666 r.executeNesting--;
11667 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011668 if (DEBUG_SERVICE) Slog.v(TAG,
11669 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011670 r.app.executingServices.remove(r);
11671 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011672 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
11673 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011674 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
11675 }
11676 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011677 if (DEBUG_SERVICE) Slog.v(TAG,
11678 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011679 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020011680 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011681 }
11682 updateOomAdjLocked(r.app);
11683 }
11684 }
11685
11686 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011687 String anrMessage = null;
11688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011689 synchronized(this) {
11690 if (proc.executingServices.size() == 0 || proc.thread == null) {
11691 return;
11692 }
11693 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
11694 Iterator<ServiceRecord> it = proc.executingServices.iterator();
11695 ServiceRecord timeout = null;
11696 long nextTime = 0;
11697 while (it.hasNext()) {
11698 ServiceRecord sr = it.next();
11699 if (sr.executingStart < maxTime) {
11700 timeout = sr;
11701 break;
11702 }
11703 if (sr.executingStart > nextTime) {
11704 nextTime = sr.executingStart;
11705 }
11706 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011707 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011708 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011709 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011710 } else {
11711 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11712 msg.obj = proc;
11713 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
11714 }
11715 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011716
11717 if (anrMessage != null) {
11718 appNotResponding(proc, null, null, anrMessage);
11719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011720 }
11721
11722 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011723 // BACKUP AND RESTORE
11724 // =========================================================
11725
11726 // Cause the target app to be launched if necessary and its backup agent
11727 // instantiated. The backup agent will invoke backupAgentCreated() on the
11728 // activity manager to announce its creation.
11729 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011730 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011731 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
11732
11733 synchronized(this) {
11734 // !!! TODO: currently no check here that we're already bound
11735 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11736 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11737 synchronized (stats) {
11738 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11739 }
11740
Dianne Hackborne7f97212011-02-24 14:40:20 -080011741 // Backup agent is now in use, its package can't be stopped.
11742 try {
11743 AppGlobals.getPackageManager().setPackageStoppedState(
11744 app.packageName, false);
11745 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011746 } catch (IllegalArgumentException e) {
11747 Slog.w(TAG, "Failed trying to unstop package "
11748 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011749 }
11750
Christopher Tate181fafa2009-05-14 11:12:14 -070011751 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011752 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11753 ? new ComponentName(app.packageName, app.backupAgentName)
11754 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011755 // startProcessLocked() returns existing proc's record if it's already running
11756 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011757 false, 0, "backup", hostingName, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011758 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011759 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011760 return false;
11761 }
11762
11763 r.app = proc;
11764 mBackupTarget = r;
11765 mBackupAppName = app.packageName;
11766
Christopher Tate6fa95972009-06-05 18:43:55 -070011767 // Try not to kill the process during backup
11768 updateOomAdjLocked(proc);
11769
Christopher Tate181fafa2009-05-14 11:12:14 -070011770 // If the process is already attached, schedule the creation of the backup agent now.
11771 // If it is not yet live, this will be done when it attaches to the framework.
11772 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011773 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011774 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011775 proc.thread.scheduleCreateBackupAgent(app,
11776 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011777 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011778 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011779 }
11780 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011781 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011782 }
11783 // Invariants: at this point, the target app process exists and the application
11784 // is either already running or in the process of coming up. mBackupTarget and
11785 // mBackupAppName describe the app, so that when it binds back to the AM we
11786 // know that it's scheduled for a backup-agent operation.
11787 }
11788
11789 return true;
11790 }
11791
11792 // A backup agent has just come up
11793 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011794 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011795 + " = " + agent);
11796
11797 synchronized(this) {
11798 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011799 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011800 return;
11801 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011802 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011803
Dianne Hackborn06740692010-09-22 22:46:21 -070011804 long oldIdent = Binder.clearCallingIdentity();
11805 try {
11806 IBackupManager bm = IBackupManager.Stub.asInterface(
11807 ServiceManager.getService(Context.BACKUP_SERVICE));
11808 bm.agentConnected(agentPackageName, agent);
11809 } catch (RemoteException e) {
11810 // can't happen; the backup manager service is local
11811 } catch (Exception e) {
11812 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11813 e.printStackTrace();
11814 } finally {
11815 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011816 }
11817 }
11818
11819 // done with this agent
11820 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011821 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011822 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011823 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011824 return;
11825 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011826
11827 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070011828 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011829 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070011830 return;
11831 }
11832
Christopher Tate181fafa2009-05-14 11:12:14 -070011833 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011834 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070011835 return;
11836 }
11837
Christopher Tate6fa95972009-06-05 18:43:55 -070011838 ProcessRecord proc = mBackupTarget.app;
11839 mBackupTarget = null;
11840 mBackupAppName = null;
11841
11842 // Not backing this app up any more; reset its OOM adjustment
11843 updateOomAdjLocked(proc);
11844
Christopher Tatec7b31e32009-06-10 15:49:30 -070011845 // If the app crashed during backup, 'thread' will be null here
11846 if (proc.thread != null) {
11847 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011848 proc.thread.scheduleDestroyBackupAgent(appInfo,
11849 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070011850 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011851 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070011852 e.printStackTrace();
11853 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011854 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011855 }
11856 }
11857 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011858 // BROADCASTS
11859 // =========================================================
11860
Josh Bartel7f208742010-02-25 11:01:44 -060011861 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011862 List cur) {
11863 final ContentResolver resolver = mContext.getContentResolver();
11864 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
11865 if (list == null) {
11866 return cur;
11867 }
11868 int N = list.size();
11869 for (int i=0; i<N; i++) {
11870 Intent intent = list.get(i);
11871 if (filter.match(resolver, intent, true, TAG) >= 0) {
11872 if (cur == null) {
11873 cur = new ArrayList<Intent>();
11874 }
11875 cur.add(intent);
11876 }
11877 }
11878 return cur;
11879 }
11880
11881 private final void scheduleBroadcastsLocked() {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011882 if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts: current="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 + mBroadcastsScheduled);
11884
11885 if (mBroadcastsScheduled) {
11886 return;
11887 }
11888 mHandler.sendEmptyMessage(BROADCAST_INTENT_MSG);
11889 mBroadcastsScheduled = true;
11890 }
11891
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011892 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011893 IIntentReceiver receiver, IntentFilter filter, String permission) {
11894 synchronized(this) {
11895 ProcessRecord callerApp = null;
11896 if (caller != null) {
11897 callerApp = getRecordForAppLocked(caller);
11898 if (callerApp == null) {
11899 throw new SecurityException(
11900 "Unable to find app for caller " + caller
11901 + " (pid=" + Binder.getCallingPid()
11902 + ") when registering receiver " + receiver);
11903 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011904 if (callerApp.info.uid != Process.SYSTEM_UID &&
11905 !callerApp.pkgList.contains(callerPackage)) {
11906 throw new SecurityException("Given caller package " + callerPackage
11907 + " is not running in process " + callerApp);
11908 }
11909 } else {
11910 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011911 }
11912
11913 List allSticky = null;
11914
11915 // Look for any matching sticky broadcasts...
11916 Iterator actions = filter.actionsIterator();
11917 if (actions != null) {
11918 while (actions.hasNext()) {
11919 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060011920 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 }
11922 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060011923 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011924 }
11925
11926 // The first sticky in the list is returned directly back to
11927 // the client.
11928 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11929
Joe Onorato8a9b2202010-02-26 18:56:32 -080011930 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011931 + ": " + sticky);
11932
11933 if (receiver == null) {
11934 return sticky;
11935 }
11936
11937 ReceiverList rl
11938 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11939 if (rl == null) {
11940 rl = new ReceiverList(this, callerApp,
11941 Binder.getCallingPid(),
11942 Binder.getCallingUid(), receiver);
11943 if (rl.app != null) {
11944 rl.app.receivers.add(rl);
11945 } else {
11946 try {
11947 receiver.asBinder().linkToDeath(rl, 0);
11948 } catch (RemoteException e) {
11949 return sticky;
11950 }
11951 rl.linkedToDeath = true;
11952 }
11953 mRegisteredReceivers.put(receiver.asBinder(), rl);
11954 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011955 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011956 rl.add(bf);
11957 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011958 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011959 }
11960 mReceiverResolver.addFilter(bf);
11961
11962 // Enqueue broadcasts for all existing stickies that match
11963 // this filter.
11964 if (allSticky != null) {
11965 ArrayList receivers = new ArrayList();
11966 receivers.add(bf);
11967
11968 int N = allSticky.size();
11969 for (int i=0; i<N; i++) {
11970 Intent intent = (Intent)allSticky.get(i);
11971 BroadcastRecord r = new BroadcastRecord(intent, null,
11972 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011973 false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011974 if (mParallelBroadcasts.size() == 0) {
11975 scheduleBroadcastsLocked();
11976 }
11977 mParallelBroadcasts.add(r);
11978 }
11979 }
11980
11981 return sticky;
11982 }
11983 }
11984
11985 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011986 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011987
11988 boolean doNext = false;
11989
11990 synchronized(this) {
11991 ReceiverList rl
11992 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11993 if (rl != null) {
11994 if (rl.curBroadcast != null) {
11995 BroadcastRecord r = rl.curBroadcast;
11996 doNext = finishReceiverLocked(
11997 receiver.asBinder(), r.resultCode, r.resultData,
11998 r.resultExtras, r.resultAbort, true);
11999 }
12000
12001 if (rl.app != null) {
12002 rl.app.receivers.remove(rl);
12003 }
12004 removeReceiverLocked(rl);
12005 if (rl.linkedToDeath) {
12006 rl.linkedToDeath = false;
12007 rl.receiver.asBinder().unlinkToDeath(rl, 0);
12008 }
12009 }
12010 }
12011
12012 if (!doNext) {
12013 return;
12014 }
12015
12016 final long origId = Binder.clearCallingIdentity();
12017 processNextBroadcast(false);
12018 trimApplications();
12019 Binder.restoreCallingIdentity(origId);
12020 }
12021
12022 void removeReceiverLocked(ReceiverList rl) {
12023 mRegisteredReceivers.remove(rl.receiver.asBinder());
12024 int N = rl.size();
12025 for (int i=0; i<N; i++) {
12026 mReceiverResolver.removeFilter(rl.get(i));
12027 }
12028 }
12029
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012030 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12031 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12032 ProcessRecord r = mLruProcesses.get(i);
12033 if (r.thread != null) {
12034 try {
12035 r.thread.dispatchPackageBroadcast(cmd, packages);
12036 } catch (RemoteException ex) {
12037 }
12038 }
12039 }
12040 }
12041
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012042 private final int broadcastIntentLocked(ProcessRecord callerApp,
12043 String callerPackage, Intent intent, String resolvedType,
12044 IIntentReceiver resultTo, int resultCode, String resultData,
12045 Bundle map, String requiredPermission,
12046 boolean ordered, boolean sticky, int callingPid, int callingUid) {
12047 intent = new Intent(intent);
12048
Dianne Hackborne7f97212011-02-24 14:40:20 -080012049 // By default broadcasts do not go to stopped apps.
12050 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12051
Joe Onorato8a9b2202010-02-26 18:56:32 -080012052 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012053 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
12054 + " ordered=" + ordered);
12055 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012056 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012057 }
12058
12059 // Handle special intents: if this broadcast is from the package
12060 // manager about a package being removed, we need to remove all of
12061 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012062 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012063 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012064 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12065 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012066 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012067 || uidRemoved) {
12068 if (checkComponentPermission(
12069 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012070 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012071 == PackageManager.PERMISSION_GRANTED) {
12072 if (uidRemoved) {
12073 final Bundle intentExtras = intent.getExtras();
12074 final int uid = intentExtras != null
12075 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12076 if (uid >= 0) {
12077 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12078 synchronized (bs) {
12079 bs.removeUidStatsLocked(uid);
12080 }
12081 }
12082 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012083 // If resources are unvailble just force stop all
12084 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012085 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012086 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12087 if (list != null && (list.length > 0)) {
12088 for (String pkg : list) {
Christopher Tate3dacd842011-08-19 14:56:15 -070012089 forceStopPackageLocked(pkg, -1, false, true, true, false);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012090 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012091 sendPackageBroadcastLocked(
12092 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012093 }
12094 } else {
12095 Uri data = intent.getData();
12096 String ssp;
12097 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12098 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12099 forceStopPackageLocked(ssp,
Christopher Tate3dacd842011-08-19 14:56:15 -070012100 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true, false);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070012101 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012102 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012103 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12104 new String[] {ssp});
12105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012106 }
12107 }
12108 }
12109 } else {
12110 String msg = "Permission Denial: " + intent.getAction()
12111 + " broadcast from " + callerPackage + " (pid=" + callingPid
12112 + ", uid=" + callingUid + ")"
12113 + " requires "
12114 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012115 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012116 throw new SecurityException(msg);
12117 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012118
12119 // Special case for adding a package: by default turn on compatibility
12120 // mode.
12121 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070012122 Uri data = intent.getData();
12123 String ssp;
12124 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12125 mCompatModePackages.handlePackageAddedLocked(ssp,
12126 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012128 }
12129
12130 /*
12131 * If this is the time zone changed action, queue up a message that will reset the timezone
12132 * of all currently running processes. This message will get queued up before the broadcast
12133 * happens.
12134 */
12135 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12136 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12137 }
12138
Robert Greenwalt03595d02010-11-02 14:08:23 -070012139 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12140 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12141 }
12142
Robert Greenwalt434203a2010-10-11 16:00:27 -070012143 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12144 ProxyProperties proxy = intent.getParcelableExtra("proxy");
12145 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12146 }
12147
Dianne Hackborn854060af2009-07-09 18:14:31 -070012148 /*
12149 * Prevent non-system code (defined here to be non-persistent
12150 * processes) from sending protected broadcasts.
12151 */
12152 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12153 || callingUid == Process.SHELL_UID || callingUid == 0) {
12154 // Always okay.
12155 } else if (callerApp == null || !callerApp.persistent) {
12156 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012157 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070012158 intent.getAction())) {
12159 String msg = "Permission Denial: not allowed to send broadcast "
12160 + intent.getAction() + " from pid="
12161 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012162 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012163 throw new SecurityException(msg);
12164 }
12165 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012166 Slog.w(TAG, "Remote exception", e);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012167 return BROADCAST_SUCCESS;
12168 }
12169 }
12170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012171 // Add to the sticky list if requested.
12172 if (sticky) {
12173 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12174 callingPid, callingUid)
12175 != PackageManager.PERMISSION_GRANTED) {
12176 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12177 + callingPid + ", uid=" + callingUid
12178 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012179 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012180 throw new SecurityException(msg);
12181 }
12182 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012183 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012184 + " and enforce permission " + requiredPermission);
12185 return BROADCAST_STICKY_CANT_HAVE_PERMISSION;
12186 }
12187 if (intent.getComponent() != null) {
12188 throw new SecurityException(
12189 "Sticky broadcasts can't target a specific component");
12190 }
12191 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12192 if (list == null) {
12193 list = new ArrayList<Intent>();
12194 mStickyBroadcasts.put(intent.getAction(), list);
12195 }
12196 int N = list.size();
12197 int i;
12198 for (i=0; i<N; i++) {
12199 if (intent.filterEquals(list.get(i))) {
12200 // This sticky already exists, replace it.
12201 list.set(i, new Intent(intent));
12202 break;
12203 }
12204 }
12205 if (i >= N) {
12206 list.add(new Intent(intent));
12207 }
12208 }
12209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012210 // Figure out who all will receive this broadcast.
12211 List receivers = null;
12212 List<BroadcastFilter> registeredReceivers = null;
12213 try {
12214 if (intent.getComponent() != null) {
12215 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012216 ActivityInfo ai = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -070012217 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012218 if (ai != null) {
12219 receivers = new ArrayList();
12220 ResolveInfo ri = new ResolveInfo();
12221 ri.activityInfo = ai;
12222 receivers.add(ri);
12223 }
12224 } else {
12225 // Need to resolve the intent to interested receivers...
12226 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
12227 == 0) {
12228 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012229 AppGlobals.getPackageManager().queryIntentReceivers(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012230 intent, resolvedType, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012231 }
Mihai Preda074edef2009-05-18 17:13:31 +020012232 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012233 }
12234 } catch (RemoteException ex) {
12235 // pm is in same process, this will never happen.
12236 }
12237
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012238 final boolean replacePending =
12239 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
12240
Joe Onorato8a9b2202010-02-26 18:56:32 -080012241 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012242 + " replacePending=" + replacePending);
12243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012244 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
12245 if (!ordered && NR > 0) {
12246 // If we are not serializing this broadcast, then send the
12247 // registered receivers separately so they don't wait for the
12248 // components to be launched.
12249 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12250 callerPackage, callingPid, callingUid, requiredPermission,
12251 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012252 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012253 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012254 TAG, "Enqueueing parallel broadcast " + r
12255 + ": prev had " + mParallelBroadcasts.size());
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012256 boolean replaced = false;
12257 if (replacePending) {
12258 for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
12259 if (intent.filterEquals(mParallelBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012260 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012261 "***** DROPPING PARALLEL: " + intent);
12262 mParallelBroadcasts.set(i, r);
12263 replaced = true;
12264 break;
12265 }
12266 }
12267 }
12268 if (!replaced) {
12269 mParallelBroadcasts.add(r);
12270 scheduleBroadcastsLocked();
12271 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012272 registeredReceivers = null;
12273 NR = 0;
12274 }
12275
12276 // Merge into one list.
12277 int ir = 0;
12278 if (receivers != null) {
12279 // A special case for PACKAGE_ADDED: do not allow the package
12280 // being added to see this broadcast. This prevents them from
12281 // using this as a back door to get run as soon as they are
12282 // installed. Maybe in the future we want to have a special install
12283 // broadcast or such for apps, but we'd like to deliberately make
12284 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012285 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012286 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
12287 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
12288 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012289 Uri data = intent.getData();
12290 if (data != null) {
12291 String pkgName = data.getSchemeSpecificPart();
12292 if (pkgName != null) {
12293 skipPackages = new String[] { pkgName };
12294 }
12295 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012296 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012297 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070012298 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012299 if (skipPackages != null && (skipPackages.length > 0)) {
12300 for (String skipPackage : skipPackages) {
12301 if (skipPackage != null) {
12302 int NT = receivers.size();
12303 for (int it=0; it<NT; it++) {
12304 ResolveInfo curt = (ResolveInfo)receivers.get(it);
12305 if (curt.activityInfo.packageName.equals(skipPackage)) {
12306 receivers.remove(it);
12307 it--;
12308 NT--;
12309 }
12310 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012311 }
12312 }
12313 }
12314
12315 int NT = receivers != null ? receivers.size() : 0;
12316 int it = 0;
12317 ResolveInfo curt = null;
12318 BroadcastFilter curr = null;
12319 while (it < NT && ir < NR) {
12320 if (curt == null) {
12321 curt = (ResolveInfo)receivers.get(it);
12322 }
12323 if (curr == null) {
12324 curr = registeredReceivers.get(ir);
12325 }
12326 if (curr.getPriority() >= curt.priority) {
12327 // Insert this broadcast record into the final list.
12328 receivers.add(it, curr);
12329 ir++;
12330 curr = null;
12331 it++;
12332 NT++;
12333 } else {
12334 // Skip to the next ResolveInfo in the final list.
12335 it++;
12336 curt = null;
12337 }
12338 }
12339 }
12340 while (ir < NR) {
12341 if (receivers == null) {
12342 receivers = new ArrayList();
12343 }
12344 receivers.add(registeredReceivers.get(ir));
12345 ir++;
12346 }
12347
12348 if ((receivers != null && receivers.size() > 0)
12349 || resultTo != null) {
12350 BroadcastRecord r = new BroadcastRecord(intent, callerApp,
12351 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012352 receivers, resultTo, resultCode, resultData, map, ordered,
12353 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012354 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012355 TAG, "Enqueueing ordered broadcast " + r
12356 + ": prev had " + mOrderedBroadcasts.size());
12357 if (DEBUG_BROADCAST) {
12358 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012359 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012360 }
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012361 boolean replaced = false;
12362 if (replacePending) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012363 for (int i=mOrderedBroadcasts.size()-1; i>0; i--) {
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012364 if (intent.filterEquals(mOrderedBroadcasts.get(i).intent)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012365 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012366 "***** DROPPING ORDERED: " + intent);
12367 mOrderedBroadcasts.set(i, r);
12368 replaced = true;
12369 break;
12370 }
12371 }
12372 }
12373 if (!replaced) {
12374 mOrderedBroadcasts.add(r);
12375 scheduleBroadcastsLocked();
12376 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012377 }
12378
12379 return BROADCAST_SUCCESS;
12380 }
12381
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012382 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012383 // Refuse possible leaked file descriptors
12384 if (intent != null && intent.hasFileDescriptors() == true) {
12385 throw new IllegalArgumentException("File descriptors passed in Intent");
12386 }
12387
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012388 int flags = intent.getFlags();
12389
12390 if (!mProcessesReady) {
12391 // if the caller really truly claims to know what they're doing, go
12392 // ahead and allow the broadcast without launching any receivers
12393 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
12394 intent = new Intent(intent);
12395 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12396 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
12397 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
12398 + " before boot completion");
12399 throw new IllegalStateException("Cannot broadcast before boot completed");
12400 }
12401 }
12402
12403 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12404 throw new IllegalArgumentException(
12405 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12406 }
12407
12408 return intent;
12409 }
12410
12411 public final int broadcastIntent(IApplicationThread caller,
12412 Intent intent, String resolvedType, IIntentReceiver resultTo,
12413 int resultCode, String resultData, Bundle map,
12414 String requiredPermission, boolean serialized, boolean sticky) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012415 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012416 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012417
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12419 final int callingPid = Binder.getCallingPid();
12420 final int callingUid = Binder.getCallingUid();
12421 final long origId = Binder.clearCallingIdentity();
12422 int res = broadcastIntentLocked(callerApp,
12423 callerApp != null ? callerApp.info.packageName : null,
12424 intent, resolvedType, resultTo,
12425 resultCode, resultData, map, requiredPermission, serialized,
12426 sticky, callingPid, callingUid);
12427 Binder.restoreCallingIdentity(origId);
12428 return res;
12429 }
12430 }
12431
12432 int broadcastIntentInPackage(String packageName, int uid,
12433 Intent intent, String resolvedType, IIntentReceiver resultTo,
12434 int resultCode, String resultData, Bundle map,
12435 String requiredPermission, boolean serialized, boolean sticky) {
12436 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012437 intent = verifyBroadcastLocked(intent);
12438
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012439 final long origId = Binder.clearCallingIdentity();
12440 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12441 resultTo, resultCode, resultData, map, requiredPermission,
12442 serialized, sticky, -1, uid);
12443 Binder.restoreCallingIdentity(origId);
12444 return res;
12445 }
12446 }
12447
12448 public final void unbroadcastIntent(IApplicationThread caller,
12449 Intent intent) {
12450 // Refuse possible leaked file descriptors
12451 if (intent != null && intent.hasFileDescriptors() == true) {
12452 throw new IllegalArgumentException("File descriptors passed in Intent");
12453 }
12454
12455 synchronized(this) {
12456 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12457 != PackageManager.PERMISSION_GRANTED) {
12458 String msg = "Permission Denial: unbroadcastIntent() from pid="
12459 + Binder.getCallingPid()
12460 + ", uid=" + Binder.getCallingUid()
12461 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012462 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012463 throw new SecurityException(msg);
12464 }
12465 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12466 if (list != null) {
12467 int N = list.size();
12468 int i;
12469 for (i=0; i<N; i++) {
12470 if (intent.filterEquals(list.get(i))) {
12471 list.remove(i);
12472 break;
12473 }
12474 }
12475 }
12476 }
12477 }
12478
12479 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12480 String resultData, Bundle resultExtras, boolean resultAbort,
12481 boolean explicit) {
12482 if (mOrderedBroadcasts.size() == 0) {
12483 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012484 Slog.w(TAG, "finishReceiver called but no pending broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012485 }
12486 return false;
12487 }
12488 BroadcastRecord r = mOrderedBroadcasts.get(0);
12489 if (r.receiver == null) {
12490 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012491 Slog.w(TAG, "finishReceiver called but none active");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012492 }
12493 return false;
12494 }
12495 if (r.receiver != receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012496 Slog.w(TAG, "finishReceiver called but active receiver is different");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012497 return false;
12498 }
12499 int state = r.state;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012500 r.state = BroadcastRecord.IDLE;
12501 if (state == BroadcastRecord.IDLE) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012502 if (explicit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012503 Slog.w(TAG, "finishReceiver called but state is IDLE");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 }
12505 }
12506 r.receiver = null;
12507 r.intent.setComponent(null);
12508 if (r.curApp != null) {
12509 r.curApp.curReceiver = null;
12510 }
12511 if (r.curFilter != null) {
12512 r.curFilter.receiverList.curBroadcast = null;
12513 }
12514 r.curFilter = null;
12515 r.curApp = null;
12516 r.curComponent = null;
12517 r.curReceiver = null;
12518 mPendingBroadcast = null;
12519
12520 r.resultCode = resultCode;
12521 r.resultData = resultData;
12522 r.resultExtras = resultExtras;
12523 r.resultAbort = resultAbort;
12524
12525 // We will process the next receiver right now if this is finishing
12526 // an app receiver (which is always asynchronous) or after we have
12527 // come back from calling a receiver.
12528 return state == BroadcastRecord.APP_RECEIVE
12529 || state == BroadcastRecord.CALL_DONE_RECEIVE;
12530 }
12531
12532 public void finishReceiver(IBinder who, int resultCode, String resultData,
12533 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012534 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012535
12536 // Refuse possible leaked file descriptors
12537 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12538 throw new IllegalArgumentException("File descriptors passed in Bundle");
12539 }
12540
12541 boolean doNext;
12542
12543 final long origId = Binder.clearCallingIdentity();
12544
12545 synchronized(this) {
12546 doNext = finishReceiverLocked(
12547 who, resultCode, resultData, resultExtras, resultAbort, true);
12548 }
12549
12550 if (doNext) {
12551 processNextBroadcast(false);
12552 }
12553 trimApplications();
12554
12555 Binder.restoreCallingIdentity(origId);
12556 }
12557
Jeff Brown4d94a762010-09-23 11:33:28 -070012558 private final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012559 if (r.nextReceiver > 0) {
12560 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12561 if (curReceiver instanceof BroadcastFilter) {
12562 BroadcastFilter bf = (BroadcastFilter) curReceiver;
Doug Zongker2bec3d42009-12-04 12:52:44 -080012563 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012564 System.identityHashCode(r),
12565 r.intent.getAction(),
12566 r.nextReceiver - 1,
12567 System.identityHashCode(bf));
12568 } else {
Doug Zongker2bec3d42009-12-04 12:52:44 -080012569 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012570 System.identityHashCode(r),
12571 r.intent.getAction(),
12572 r.nextReceiver - 1,
12573 ((ResolveInfo)curReceiver).toString());
12574 }
12575 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012576 Slog.w(TAG, "Discarding broadcast before first receiver is invoked: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012577 + r);
Doug Zongker2bec3d42009-12-04 12:52:44 -080012578 EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012579 System.identityHashCode(r),
12580 r.intent.getAction(),
12581 r.nextReceiver,
12582 "NONE");
12583 }
12584 }
12585
Jeff Brown4d94a762010-09-23 11:33:28 -070012586 private final void setBroadcastTimeoutLocked(long timeoutTime) {
12587 if (! mPendingBroadcastTimeoutMessage) {
12588 Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG);
12589 mHandler.sendMessageAtTime(msg, timeoutTime);
12590 mPendingBroadcastTimeoutMessage = true;
12591 }
12592 }
12593
12594 private final void cancelBroadcastTimeoutLocked() {
12595 if (mPendingBroadcastTimeoutMessage) {
12596 mHandler.removeMessages(BROADCAST_TIMEOUT_MSG);
12597 mPendingBroadcastTimeoutMessage = false;
12598 }
12599 }
12600
12601 private final void broadcastTimeoutLocked(boolean fromMsg) {
12602 if (fromMsg) {
12603 mPendingBroadcastTimeoutMessage = false;
12604 }
12605
12606 if (mOrderedBroadcasts.size() == 0) {
12607 return;
12608 }
12609
12610 long now = SystemClock.uptimeMillis();
12611 BroadcastRecord r = mOrderedBroadcasts.get(0);
12612 if (fromMsg) {
12613 if (mDidDexOpt) {
12614 // Delay timeouts until dexopt finishes.
12615 mDidDexOpt = false;
12616 long timeoutTime = SystemClock.uptimeMillis() + BROADCAST_TIMEOUT;
12617 setBroadcastTimeoutLocked(timeoutTime);
12618 return;
12619 }
12620 if (! mProcessesReady) {
12621 // Only process broadcast timeouts if the system is ready. That way
12622 // PRE_BOOT_COMPLETED broadcasts can't timeout as they are intended
12623 // to do heavy lifting for system up.
12624 return;
12625 }
12626
12627 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
12628 if (timeoutTime > now) {
12629 // We can observe premature timeouts because we do not cancel and reset the
12630 // broadcast timeout message after each receiver finishes. Instead, we set up
12631 // an initial timeout then kick it down the road a little further as needed
12632 // when it expires.
12633 if (DEBUG_BROADCAST) Slog.v(TAG,
12634 "Premature timeout @ " + now + ": resetting BROADCAST_TIMEOUT_MSG for "
12635 + timeoutTime);
12636 setBroadcastTimeoutLocked(timeoutTime);
12637 return;
12638 }
12639 }
12640
12641 Slog.w(TAG, "Timeout of broadcast " + r + " - receiver=" + r.receiver
12642 + ", started " + (now - r.receiverTime) + "ms ago");
12643 r.receiverTime = now;
12644 r.anrCount++;
12645
12646 // Current receiver has passed its expiration date.
12647 if (r.nextReceiver <= 0) {
12648 Slog.w(TAG, "Timeout on receiver with nextReceiver <= 0");
12649 return;
12650 }
12651
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012652 ProcessRecord app = null;
12653 String anrMessage = null;
12654
Jeff Brown4d94a762010-09-23 11:33:28 -070012655 Object curReceiver = r.receivers.get(r.nextReceiver-1);
12656 Slog.w(TAG, "Receiver during timeout: " + curReceiver);
12657 logBroadcastReceiverDiscardLocked(r);
12658 if (curReceiver instanceof BroadcastFilter) {
12659 BroadcastFilter bf = (BroadcastFilter)curReceiver;
12660 if (bf.receiverList.pid != 0
12661 && bf.receiverList.pid != MY_PID) {
12662 synchronized (this.mPidsSelfLocked) {
12663 app = this.mPidsSelfLocked.get(
12664 bf.receiverList.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012665 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012666 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012667 } else {
12668 app = r.curApp;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012669 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012670
Jeff Brown4d94a762010-09-23 11:33:28 -070012671 if (app != null) {
12672 anrMessage = "Broadcast of " + r.intent.toString();
12673 }
12674
12675 if (mPendingBroadcast == r) {
12676 mPendingBroadcast = null;
12677 }
12678
12679 // Move on to the next receiver.
12680 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
12681 r.resultExtras, r.resultAbort, true);
12682 scheduleBroadcastsLocked();
12683
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012684 if (anrMessage != null) {
Jeff Brown4d94a762010-09-23 11:33:28 -070012685 // Post the ANR to the handler since we do not want to process ANRs while
12686 // potentially holding our lock.
12687 mHandler.post(new AppNotResponding(app, anrMessage));
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012688 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012689 }
12690
12691 private final void processCurBroadcastLocked(BroadcastRecord r,
12692 ProcessRecord app) throws RemoteException {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012693 if (DEBUG_BROADCAST) Slog.v(TAG,
12694 "Process cur broadcast " + r + " for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012695 if (app.thread == null) {
12696 throw new RemoteException();
12697 }
12698 r.receiver = app.thread.asBinder();
12699 r.curApp = app;
12700 app.curReceiver = r;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012701 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012702
12703 // Tell the application to launch this receiver.
12704 r.intent.setComponent(r.curComponent);
12705
12706 boolean started = false;
12707 try {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012708 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012709 "Delivering to component " + r.curComponent
12710 + ": " + r);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070012711 ensurePackageDexOpt(r.intent.getComponent().getPackageName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012712 app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012713 compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012714 r.resultCode, r.resultData, r.resultExtras, r.ordered);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012715 if (DEBUG_BROADCAST) Slog.v(TAG,
12716 "Process cur broadcast " + r + " DELIVERED for app " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012717 started = true;
12718 } finally {
12719 if (!started) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012720 if (DEBUG_BROADCAST) Slog.v(TAG,
12721 "Process cur broadcast " + r + ": NOT STARTED!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012722 r.receiver = null;
12723 r.curApp = null;
12724 app.curReceiver = null;
12725 }
12726 }
12727
12728 }
12729
Jeff Brown4d94a762010-09-23 11:33:28 -070012730 static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012731 Intent intent, int resultCode, String data, Bundle extras,
12732 boolean ordered, boolean sticky) throws RemoteException {
Jeff Brown4d94a762010-09-23 11:33:28 -070012733 // Send the intent to the receiver asynchronously using one-way binder calls.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012734 if (app != null && app.thread != null) {
12735 // If we have an app thread, do the call through that so it is
12736 // correctly ordered with other one-way calls.
12737 app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012738 data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012739 } else {
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012740 receiver.performReceive(intent, resultCode, data, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012741 }
12742 }
12743
Jeff Brown4d94a762010-09-23 11:33:28 -070012744 private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012745 BroadcastFilter filter, boolean ordered) {
12746 boolean skip = false;
12747 if (filter.requiredPermission != null) {
12748 int perm = checkComponentPermission(filter.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012749 r.callingPid, r.callingUid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012750 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012751 Slog.w(TAG, "Permission Denial: broadcasting "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012752 + r.intent.toString()
12753 + " from " + r.callerPackage + " (pid="
12754 + r.callingPid + ", uid=" + r.callingUid + ")"
12755 + " requires " + filter.requiredPermission
12756 + " due to registered receiver " + filter);
12757 skip = true;
12758 }
12759 }
12760 if (r.requiredPermission != null) {
12761 int perm = checkComponentPermission(r.requiredPermission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012762 filter.receiverList.pid, filter.receiverList.uid, -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012763 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012764 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012765 + r.intent.toString()
12766 + " to " + filter.receiverList.app
12767 + " (pid=" + filter.receiverList.pid
12768 + ", uid=" + filter.receiverList.uid + ")"
12769 + " requires " + r.requiredPermission
12770 + " due to sender " + r.callerPackage
12771 + " (uid " + r.callingUid + ")");
12772 skip = true;
12773 }
12774 }
12775
12776 if (!skip) {
12777 // If this is not being sent as an ordered broadcast, then we
12778 // don't want to touch the fields that keep track of the current
12779 // state of ordered broadcasts.
12780 if (ordered) {
12781 r.receiver = filter.receiverList.receiver.asBinder();
12782 r.curFilter = filter;
12783 filter.receiverList.curBroadcast = r;
12784 r.state = BroadcastRecord.CALL_IN_RECEIVE;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012785 if (filter.receiverList.app != null) {
12786 // Bump hosting application to no longer be in background
12787 // scheduling class. Note that we can't do that if there
12788 // isn't an app... but we can only be in that case for
12789 // things that directly call the IActivityManager API, which
12790 // are already core system stuff so don't matter for this.
12791 r.curApp = filter.receiverList.app;
12792 filter.receiverList.app.curReceiver = r;
12793 updateOomAdjLocked();
12794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012795 }
12796 try {
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012797 if (DEBUG_BROADCAST_LIGHT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012798 int seq = r.intent.getIntExtra("seq", -1);
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012799 Slog.i(TAG, "Delivering to " + filter
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012800 + " (seq=" + seq + "): " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012801 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012802 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012803 new Intent(r.intent), r.resultCode,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012804 r.resultData, r.resultExtras, r.ordered, r.initialSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012805 if (ordered) {
12806 r.state = BroadcastRecord.CALL_DONE_RECEIVE;
12807 }
12808 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012809 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012810 if (ordered) {
12811 r.receiver = null;
12812 r.curFilter = null;
12813 filter.receiverList.curBroadcast = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012814 if (filter.receiverList.app != null) {
12815 filter.receiverList.app.curReceiver = null;
12816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012817 }
12818 }
12819 }
12820 }
12821
Dianne Hackborn12527f92009-11-11 17:39:50 -080012822 private final void addBroadcastToHistoryLocked(BroadcastRecord r) {
12823 if (r.callingUid < 0) {
12824 // This was from a registerReceiver() call; ignore it.
12825 return;
12826 }
12827 System.arraycopy(mBroadcastHistory, 0, mBroadcastHistory, 1,
12828 MAX_BROADCAST_HISTORY-1);
12829 r.finishTime = SystemClock.uptimeMillis();
12830 mBroadcastHistory[0] = r;
12831 }
12832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012833 private final void processNextBroadcast(boolean fromMsg) {
12834 synchronized(this) {
12835 BroadcastRecord r;
12836
Joe Onorato8a9b2202010-02-26 18:56:32 -080012837 if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012838 + mParallelBroadcasts.size() + " broadcasts, "
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012839 + mOrderedBroadcasts.size() + " ordered broadcasts");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012840
12841 updateCpuStats();
12842
12843 if (fromMsg) {
12844 mBroadcastsScheduled = false;
12845 }
12846
12847 // First, deliver any non-serialized broadcasts right away.
12848 while (mParallelBroadcasts.size() > 0) {
12849 r = mParallelBroadcasts.remove(0);
Dianne Hackborn12527f92009-11-11 17:39:50 -080012850 r.dispatchTime = SystemClock.uptimeMillis();
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012851 r.dispatchClockTime = System.currentTimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012852 final int N = r.receivers.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012853 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012854 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012855 for (int i=0; i<N; i++) {
12856 Object target = r.receivers.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012857 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070012858 "Delivering non-ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012859 + target + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012860 deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012861 }
Dianne Hackborn12527f92009-11-11 17:39:50 -080012862 addBroadcastToHistoryLocked(r);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012863 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012864 + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012865 }
12866
12867 // Now take care of the next serialized one...
12868
12869 // If we are waiting for a process to come up to handle the next
12870 // broadcast, then do nothing at this point. Just in case, we
12871 // check that the process we're waiting for still exists.
12872 if (mPendingBroadcast != null) {
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012873 if (DEBUG_BROADCAST_LIGHT) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012874 Slog.v(TAG, "processNextBroadcast: waiting for "
Dianne Hackbornbd0a81f2009-10-04 13:30:50 -070012875 + mPendingBroadcast.curApp);
12876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012877
12878 boolean isDead;
12879 synchronized (mPidsSelfLocked) {
12880 isDead = (mPidsSelfLocked.get(mPendingBroadcast.curApp.pid) == null);
12881 }
12882 if (!isDead) {
12883 // It's still alive, so keep waiting
12884 return;
12885 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012886 Slog.w(TAG, "pending app " + mPendingBroadcast.curApp
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012887 + " died before responding to broadcast");
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012888 mPendingBroadcast.state = BroadcastRecord.IDLE;
12889 mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012890 mPendingBroadcast = null;
12891 }
12892 }
12893
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012894 boolean looped = false;
12895
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012896 do {
12897 if (mOrderedBroadcasts.size() == 0) {
12898 // No more broadcasts pending, so all done!
12899 scheduleAppGcsLocked();
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012900 if (looped) {
12901 // If we had finished the last ordered broadcast, then
12902 // make sure all processes have correct oom and sched
12903 // adjustments.
12904 updateOomAdjLocked();
12905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012906 return;
12907 }
12908 r = mOrderedBroadcasts.get(0);
12909 boolean forceReceive = false;
12910
12911 // Ensure that even if something goes awry with the timeout
12912 // detection, we catch "hung" broadcasts here, discard them,
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012913 // and continue to make progress.
12914 //
12915 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
Jeff Brown4d94a762010-09-23 11:33:28 -070012916 // receivers don't get executed with timeouts. They're intended for
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012917 // one time heavy lifting after system upgrades and can take
12918 // significant amounts of time.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012919 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012920 if (mProcessesReady && r.dispatchTime > 0) {
Jeff Hamiltonacf84742010-05-25 22:10:18 -050012921 long now = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012922 if ((numReceivers > 0) &&
12923 (now > r.dispatchTime + (2*BROADCAST_TIMEOUT*numReceivers))) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012924 Slog.w(TAG, "Hung broadcast discarded after timeout failure:"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012925 + " now=" + now
12926 + " dispatchTime=" + r.dispatchTime
Dianne Hackborn12527f92009-11-11 17:39:50 -080012927 + " startTime=" + r.receiverTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012928 + " intent=" + r.intent
12929 + " numReceivers=" + numReceivers
12930 + " nextReceiver=" + r.nextReceiver
12931 + " state=" + r.state);
Jeff Brown4d94a762010-09-23 11:33:28 -070012932 broadcastTimeoutLocked(false); // forcibly finish this broadcast
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012933 forceReceive = true;
12934 r.state = BroadcastRecord.IDLE;
12935 }
12936 }
12937
12938 if (r.state != BroadcastRecord.IDLE) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012939 if (DEBUG_BROADCAST) Slog.d(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012940 "processNextBroadcast() called when not idle (state="
12941 + r.state + ")");
12942 return;
12943 }
12944
12945 if (r.receivers == null || r.nextReceiver >= numReceivers
12946 || r.resultAbort || forceReceive) {
12947 // No more receivers for this broadcast! Send the final
12948 // result if requested...
12949 if (r.resultTo != null) {
12950 try {
12951 if (DEBUG_BROADCAST) {
12952 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012953 Slog.i(TAG, "Finishing broadcast " + r.intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012954 + " seq=" + seq + " app=" + r.callerApp);
12955 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012956 performReceiveLocked(r.callerApp, r.resultTo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012957 new Intent(r.intent), r.resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -070012958 r.resultData, r.resultExtras, false, false);
Johannes Carlssonb5a86542010-10-27 10:08:10 +020012959 // Set this to null so that the reference
12960 // (local and remote) isnt kept in the mBroadcastHistory.
12961 r.resultTo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012962 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012963 Slog.w(TAG, "Failure sending broadcast result of " + r.intent, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012964 }
12965 }
12966
Joe Onorato8a9b2202010-02-26 18:56:32 -080012967 if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
Jeff Brown4d94a762010-09-23 11:33:28 -070012968 cancelBroadcastTimeoutLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012969
Joe Onorato8a9b2202010-02-26 18:56:32 -080012970 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012971 + r);
12972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012973 // ... and on to the next...
Dianne Hackborn12527f92009-11-11 17:39:50 -080012974 addBroadcastToHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012975 mOrderedBroadcasts.remove(0);
12976 r = null;
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012977 looped = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012978 continue;
12979 }
12980 } while (r == null);
12981
12982 // Get the next receiver...
12983 int recIdx = r.nextReceiver++;
12984
12985 // Keep track of when this receiver started, and make sure there
12986 // is a timeout message pending to kill it if need be.
Dianne Hackborn12527f92009-11-11 17:39:50 -080012987 r.receiverTime = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012988 if (recIdx == 0) {
Dianne Hackborn12527f92009-11-11 17:39:50 -080012989 r.dispatchTime = r.receiverTime;
Dianne Hackbornd99b2932011-08-18 14:39:58 -070012990 r.dispatchClockTime = System.currentTimeMillis();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012991 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast "
Dianne Hackborn82f3f002009-06-16 18:49:05 -070012992 + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070012993 }
12994 if (! mPendingBroadcastTimeoutMessage) {
12995 long timeoutTime = r.receiverTime + BROADCAST_TIMEOUT;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012996 if (DEBUG_BROADCAST) Slog.v(TAG,
Jeff Brown4d94a762010-09-23 11:33:28 -070012997 "Submitting BROADCAST_TIMEOUT_MSG for " + r + " at " + timeoutTime);
12998 setBroadcastTimeoutLocked(timeoutTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012999 }
13000
13001 Object nextReceiver = r.receivers.get(recIdx);
13002 if (nextReceiver instanceof BroadcastFilter) {
13003 // Simple case: this is a registered receiver who gets
13004 // a direct call.
13005 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013006 if (DEBUG_BROADCAST) Slog.v(TAG,
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013007 "Delivering ordered to registered "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013008 + filter + ": " + r);
Jeff Brown4d94a762010-09-23 11:33:28 -070013009 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013010 if (r.receiver == null || !r.ordered) {
13011 // The receiver has already finished, so schedule to
13012 // process the next one.
Dianne Hackborn399cccb2010-04-13 22:57:49 -070013013 if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing: ordered="
13014 + r.ordered + " receiver=" + r.receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013015 r.state = BroadcastRecord.IDLE;
13016 scheduleBroadcastsLocked();
13017 }
13018 return;
13019 }
13020
13021 // Hard case: need to instantiate the receiver, possibly
13022 // starting its application process to host it.
13023
13024 ResolveInfo info =
13025 (ResolveInfo)nextReceiver;
13026
13027 boolean skip = false;
13028 int perm = checkComponentPermission(info.activityInfo.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013029 r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
13030 info.activityInfo.exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013031 if (perm != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080013032 if (!info.activityInfo.exported) {
13033 Slog.w(TAG, "Permission Denial: broadcasting "
13034 + r.intent.toString()
13035 + " from " + r.callerPackage + " (pid=" + r.callingPid
13036 + ", uid=" + r.callingUid + ")"
13037 + " is not exported from uid " + info.activityInfo.applicationInfo.uid
13038 + " due to receiver " + info.activityInfo.packageName
13039 + "/" + info.activityInfo.name);
13040 } else {
13041 Slog.w(TAG, "Permission Denial: broadcasting "
13042 + r.intent.toString()
13043 + " from " + r.callerPackage + " (pid=" + r.callingPid
13044 + ", uid=" + r.callingUid + ")"
13045 + " requires " + info.activityInfo.permission
13046 + " due to receiver " + info.activityInfo.packageName
13047 + "/" + info.activityInfo.name);
13048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013049 skip = true;
13050 }
Dianne Hackbornd99b2932011-08-18 14:39:58 -070013051 if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013052 r.requiredPermission != null) {
13053 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013054 perm = AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013055 checkPermission(r.requiredPermission,
13056 info.activityInfo.applicationInfo.packageName);
13057 } catch (RemoteException e) {
13058 perm = PackageManager.PERMISSION_DENIED;
13059 }
13060 if (perm != PackageManager.PERMISSION_GRANTED) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013061 Slog.w(TAG, "Permission Denial: receiving "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013062 + r.intent + " to "
13063 + info.activityInfo.applicationInfo.packageName
13064 + " requires " + r.requiredPermission
13065 + " due to sender " + r.callerPackage
13066 + " (uid " + r.callingUid + ")");
13067 skip = true;
13068 }
13069 }
13070 if (r.curApp != null && r.curApp.crashing) {
13071 // If the target process is crashing, just skip it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013072 if (DEBUG_BROADCAST) Slog.v(TAG,
13073 "Skipping deliver ordered " + r + " to " + r.curApp
13074 + ": process crashing");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013075 skip = true;
13076 }
13077
13078 if (skip) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013079 if (DEBUG_BROADCAST) Slog.v(TAG,
13080 "Skipping delivery of ordered " + r + " for whatever reason");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013081 r.receiver = null;
13082 r.curFilter = null;
13083 r.state = BroadcastRecord.IDLE;
13084 scheduleBroadcastsLocked();
13085 return;
13086 }
13087
13088 r.state = BroadcastRecord.APP_RECEIVE;
13089 String targetProcess = info.activityInfo.processName;
13090 r.curComponent = new ComponentName(
13091 info.activityInfo.applicationInfo.packageName,
13092 info.activityInfo.name);
13093 r.curReceiver = info.activityInfo;
13094
Dianne Hackborne7f97212011-02-24 14:40:20 -080013095 // Broadcast is being executed, its package can't be stopped.
13096 try {
13097 AppGlobals.getPackageManager().setPackageStoppedState(
13098 r.curComponent.getPackageName(), false);
13099 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080013100 } catch (IllegalArgumentException e) {
13101 Slog.w(TAG, "Failed trying to unstop package "
13102 + r.curComponent.getPackageName() + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080013103 }
13104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013105 // Is this receiver's application already running?
13106 ProcessRecord app = getProcessRecordLocked(targetProcess,
13107 info.activityInfo.applicationInfo.uid);
13108 if (app != null && app.thread != null) {
13109 try {
Dianne Hackborn6c418d52011-06-29 14:05:33 -070013110 app.addPackage(info.activityInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013111 processCurBroadcastLocked(r, app);
13112 return;
13113 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013114 Slog.w(TAG, "Exception when sending broadcast to "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013115 + r.curComponent, e);
13116 }
13117
13118 // If a dead object exception was thrown -- fall through to
13119 // restart the application.
13120 }
13121
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013122 // Not running -- get it started, to be executed when the app comes up.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013123 if (DEBUG_BROADCAST) Slog.v(TAG,
13124 "Need to start app " + targetProcess + " for broadcast " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013125 if ((r.curApp=startProcessLocked(targetProcess,
13126 info.activityInfo.applicationInfo, true,
13127 r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013128 "broadcast", r.curComponent,
13129 (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0))
13130 == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013131 // Ah, this recipient is unavailable. Finish it if necessary,
13132 // and mark the broadcast record as ready for the next.
Joe Onorato8a9b2202010-02-26 18:56:32 -080013133 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013134 + info.activityInfo.applicationInfo.packageName + "/"
13135 + info.activityInfo.applicationInfo.uid + " for broadcast "
13136 + r.intent + ": process is bad");
Jeff Brown4d94a762010-09-23 11:33:28 -070013137 logBroadcastReceiverDiscardLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 finishReceiverLocked(r.receiver, r.resultCode, r.resultData,
13139 r.resultExtras, r.resultAbort, true);
13140 scheduleBroadcastsLocked();
13141 r.state = BroadcastRecord.IDLE;
13142 return;
13143 }
13144
13145 mPendingBroadcast = r;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013146 mPendingBroadcastRecvIndex = recIdx;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013147 }
13148 }
13149
13150 // =========================================================
13151 // INSTRUMENTATION
13152 // =========================================================
13153
13154 public boolean startInstrumentation(ComponentName className,
13155 String profileFile, int flags, Bundle arguments,
13156 IInstrumentationWatcher watcher) {
13157 // Refuse possible leaked file descriptors
13158 if (arguments != null && arguments.hasFileDescriptors()) {
13159 throw new IllegalArgumentException("File descriptors passed in Bundle");
13160 }
13161
13162 synchronized(this) {
13163 InstrumentationInfo ii = null;
13164 ApplicationInfo ai = null;
13165 try {
13166 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013167 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013168 ai = mContext.getPackageManager().getApplicationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013169 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013170 } catch (PackageManager.NameNotFoundException e) {
13171 }
13172 if (ii == null) {
13173 reportStartInstrumentationFailure(watcher, className,
13174 "Unable to find instrumentation info for: " + className);
13175 return false;
13176 }
13177 if (ai == null) {
13178 reportStartInstrumentationFailure(watcher, className,
13179 "Unable to find instrumentation target package: " + ii.targetPackage);
13180 return false;
13181 }
13182
13183 int match = mContext.getPackageManager().checkSignatures(
13184 ii.targetPackage, ii.packageName);
13185 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13186 String msg = "Permission Denial: starting instrumentation "
13187 + className + " from pid="
13188 + Binder.getCallingPid()
13189 + ", uid=" + Binder.getCallingPid()
13190 + " not allowed because package " + ii.packageName
13191 + " does not have a signature matching the target "
13192 + ii.targetPackage;
13193 reportStartInstrumentationFailure(watcher, className, msg);
13194 throw new SecurityException(msg);
13195 }
13196
13197 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013198 // Instrumentation can kill and relaunch even persistent processes
13199 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013200 ProcessRecord app = addAppLocked(ai);
13201 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013202 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013203 app.instrumentationProfileFile = profileFile;
13204 app.instrumentationArguments = arguments;
13205 app.instrumentationWatcher = watcher;
13206 app.instrumentationResultClass = className;
13207 Binder.restoreCallingIdentity(origId);
13208 }
13209
13210 return true;
13211 }
13212
13213 /**
13214 * Report errors that occur while attempting to start Instrumentation. Always writes the
13215 * error to the logs, but if somebody is watching, send the report there too. This enables
13216 * the "am" command to report errors with more information.
13217 *
13218 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13219 * @param cn The component name of the instrumentation.
13220 * @param report The error report.
13221 */
13222 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13223 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013224 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013225 try {
13226 if (watcher != null) {
13227 Bundle results = new Bundle();
13228 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13229 results.putString("Error", report);
13230 watcher.instrumentationStatus(cn, -1, results);
13231 }
13232 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013233 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013234 }
13235 }
13236
13237 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13238 if (app.instrumentationWatcher != null) {
13239 try {
13240 // NOTE: IInstrumentationWatcher *must* be oneway here
13241 app.instrumentationWatcher.instrumentationFinished(
13242 app.instrumentationClass,
13243 resultCode,
13244 results);
13245 } catch (RemoteException e) {
13246 }
13247 }
13248 app.instrumentationWatcher = null;
13249 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013250 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013251 app.instrumentationProfileFile = null;
13252 app.instrumentationArguments = null;
13253
Christopher Tate3dacd842011-08-19 14:56:15 -070013254 forceStopPackageLocked(app.processName, -1, false, false, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013255 }
13256
13257 public void finishInstrumentation(IApplicationThread target,
13258 int resultCode, Bundle results) {
13259 // Refuse possible leaked file descriptors
13260 if (results != null && results.hasFileDescriptors()) {
13261 throw new IllegalArgumentException("File descriptors passed in Intent");
13262 }
13263
13264 synchronized(this) {
13265 ProcessRecord app = getRecordForAppLocked(target);
13266 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013267 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013268 return;
13269 }
13270 final long origId = Binder.clearCallingIdentity();
13271 finishInstrumentationLocked(app, resultCode, results);
13272 Binder.restoreCallingIdentity(origId);
13273 }
13274 }
13275
13276 // =========================================================
13277 // CONFIGURATION
13278 // =========================================================
13279
13280 public ConfigurationInfo getDeviceConfigurationInfo() {
13281 ConfigurationInfo config = new ConfigurationInfo();
13282 synchronized (this) {
13283 config.reqTouchScreen = mConfiguration.touchscreen;
13284 config.reqKeyboardType = mConfiguration.keyboard;
13285 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013286 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13287 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013288 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13289 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013290 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13291 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13293 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013294 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013295 }
13296 return config;
13297 }
13298
13299 public Configuration getConfiguration() {
13300 Configuration ci;
13301 synchronized(this) {
13302 ci = new Configuration(mConfiguration);
13303 }
13304 return ci;
13305 }
13306
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013307 public void updatePersistentConfiguration(Configuration values) {
13308 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13309 "updateConfiguration()");
13310 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13311 "updateConfiguration()");
13312 if (values == null) {
13313 throw new NullPointerException("Configuration must not be null");
13314 }
13315
13316 synchronized(this) {
13317 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013318 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013319 Binder.restoreCallingIdentity(origId);
13320 }
13321 }
13322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 public void updateConfiguration(Configuration values) {
13324 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13325 "updateConfiguration()");
13326
13327 synchronized(this) {
13328 if (values == null && mWindowManager != null) {
13329 // sentinel: fetch the current configuration from the window manager
13330 values = mWindowManager.computeNewConfiguration();
13331 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013332
13333 if (mWindowManager != null) {
13334 mProcessList.applyDisplaySize(mWindowManager);
13335 }
13336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013337 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013338 if (values != null) {
13339 Settings.System.clearConfiguration(values);
13340 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013341 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013342 Binder.restoreCallingIdentity(origId);
13343 }
13344 }
13345
13346 /**
13347 * Do either or both things: (1) change the current configuration, and (2)
13348 * make sure the given activity is running with the (now) current
13349 * configuration. Returns true if the activity has been left running, or
13350 * false if <var>starting</var> is being destroyed to match the new
13351 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013352 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013353 */
13354 public boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013355 ActivityRecord starting, boolean persistent, boolean initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013356 int changes = 0;
13357
13358 boolean kept = true;
13359
13360 if (values != null) {
13361 Configuration newConfig = new Configuration(mConfiguration);
13362 changes = newConfig.updateFrom(values);
13363 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013364 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013365 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013366 }
13367
Doug Zongker2bec3d42009-12-04 12:52:44 -080013368 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013369
Dianne Hackborn813075a62011-11-14 17:45:19 -080013370 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013371 saveLocaleLocked(values.locale,
13372 !values.locale.equals(mConfiguration.locale),
13373 values.userSetLocale);
13374 }
13375
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013376 mConfigurationSeq++;
13377 if (mConfigurationSeq <= 0) {
13378 mConfigurationSeq = 1;
13379 }
13380 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013381 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013382 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013383
13384 final Configuration configCopy = new Configuration(mConfiguration);
13385
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013386 AttributeCache ac = AttributeCache.instance();
13387 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013388 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013389 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013390
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013391 // Make sure all resources in our process are updated
13392 // right now, so that anyone who is going to retrieve
13393 // resource values after we return will be sure to get
13394 // the new ones. This is especially important during
13395 // boot, where the first config change needs to guarantee
13396 // all resources have that config before following boot
13397 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013398 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013399
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013400 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013401 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013402 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013403 mHandler.sendMessage(msg);
13404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013405
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013406 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13407 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013408 try {
13409 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013410 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013411 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013412 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013413 }
13414 } catch (Exception e) {
13415 }
13416 }
13417 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13419 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013420 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
13421 null, false, false, MY_PID, Process.SYSTEM_UID);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013422 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13423 broadcastIntentLocked(null, null,
13424 new Intent(Intent.ACTION_LOCALE_CHANGED),
13425 null, null, 0, null, null,
13426 null, false, false, MY_PID, Process.SYSTEM_UID);
13427 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013428 }
13429 }
13430
13431 if (changes != 0 && starting == null) {
13432 // If the configuration changed, and the caller is not already
13433 // in the process of starting an activity, then find the top
13434 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013435 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013436 }
13437
13438 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013439 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013440 // And we need to make sure at this point that all other activities
13441 // are made visible with the correct configuration.
13442 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013443 }
13444
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013445 if (values != null && mWindowManager != null) {
13446 mWindowManager.setNewConfiguration(mConfiguration);
13447 }
13448
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013449 return kept;
13450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013451
13452 /**
13453 * Save the locale. You must be inside a synchronized (this) block.
13454 */
13455 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13456 if(isDiff) {
13457 SystemProperties.set("user.language", l.getLanguage());
13458 SystemProperties.set("user.region", l.getCountry());
13459 }
13460
13461 if(isPersist) {
13462 SystemProperties.set("persist.sys.language", l.getLanguage());
13463 SystemProperties.set("persist.sys.country", l.getCountry());
13464 SystemProperties.set("persist.sys.localevar", l.getVariant());
13465 }
13466 }
13467
13468 // =========================================================
13469 // LIFETIME MANAGEMENT
13470 // =========================================================
13471
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013472 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013473 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013474 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013475 // This adjustment has already been computed. If we are calling
13476 // from the top, we may have already computed our adjustment with
13477 // an earlier hidden adjustment that isn't really for us... if
13478 // so, use the new hidden adjustment.
13479 if (!recursed && app.hidden) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013480 app.curAdj = app.curRawAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013481 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013482 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013483 }
13484
13485 if (app.thread == null) {
13486 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013487 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013488 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013489 }
13490
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013491 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13492 app.adjSource = null;
13493 app.adjTarget = null;
13494 app.empty = false;
13495 app.hidden = false;
13496
13497 final int activitiesSize = app.activities.size();
13498
Dianne Hackborn7d608422011-08-07 16:24:18 -070013499 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013500 // The max adjustment doesn't allow this app to be anything
13501 // below foreground, so it is not worth doing work for it.
13502 app.adjType = "fixed";
13503 app.adjSeq = mAdjSeq;
13504 app.curRawAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013505 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013506 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013507 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013508 // System process can do UI, and when they do we want to have
13509 // them trim their memory after the user leaves the UI. To
13510 // facilitate this, here we need to determine whether or not it
13511 // is currently showing UI.
13512 app.systemNoUi = true;
13513 if (app == TOP_APP) {
13514 app.systemNoUi = false;
13515 } else if (activitiesSize > 0) {
13516 for (int j = 0; j < activitiesSize; j++) {
13517 final ActivityRecord r = app.activities.get(j);
13518 if (r.visible) {
13519 app.systemNoUi = false;
13520 break;
13521 }
13522 }
13523 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013524 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013525 }
13526
13527 final boolean hadForegroundActivities = app.foregroundActivities;
13528
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013529 app.foregroundActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013530 app.keeping = false;
13531 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013532
The Android Open Source Project4df24232009-03-05 14:34:35 -080013533 // Determine the importance of the process, starting with most
13534 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013535 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013536 int schedGroup;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013537 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013538 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013539 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013540 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013541 app.adjType = "top-activity";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013542 app.foregroundActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013543 } else if (app.instrumentationClass != null) {
13544 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013545 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013546 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013547 app.adjType = "instrumentation";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013548 } else if (app.curReceiver != null ||
13549 (mPendingBroadcast != null && mPendingBroadcast.curApp == app)) {
13550 // An app that is currently receiving a broadcast also
13551 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013552 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013553 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013554 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013555 } else if (app.executingServices.size() > 0) {
13556 // An app that is currently executing a service callback also
13557 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013558 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013559 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013560 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013561 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013562 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013563 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013564 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013565 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013566 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013567 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013568 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013569 // A very not-needed process. If this is lower in the lru list,
13570 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013571 adj = hiddenAdj;
13572 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013573 app.hidden = true;
13574 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013575 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013576 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013577
13578 // Examine all activities if not already foreground.
13579 if (!app.foregroundActivities && activitiesSize > 0) {
13580 for (int j = 0; j < activitiesSize; j++) {
13581 final ActivityRecord r = app.activities.get(j);
13582 if (r.visible) {
13583 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013584 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13585 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013586 app.adjType = "visible";
13587 }
13588 schedGroup = Process.THREAD_GROUP_DEFAULT;
13589 app.hidden = false;
13590 app.foregroundActivities = true;
13591 break;
13592 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED
13593 || r.state == ActivityState.STOPPING) {
13594 // Only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013595 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13596 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013597 app.adjType = "stopping";
13598 }
13599 app.foregroundActivities = true;
13600 }
13601 }
13602 }
13603
Dianne Hackborn7d608422011-08-07 16:24:18 -070013604 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013605 if (app.foregroundServices) {
13606 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013607 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013608 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013609 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013610 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013611 } else if (app.forcingToForeground != null) {
13612 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013613 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013614 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013615 app.adjType = "force-foreground";
13616 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013617 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013618 }
13619 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013620
Dianne Hackborn7d608422011-08-07 16:24:18 -070013621 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013622 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013623 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013624 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013625 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013626 app.adjType = "heavy";
13627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013628
Dianne Hackborn7d608422011-08-07 16:24:18 -070013629 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013630 // This process is hosting what we currently consider to be the
13631 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013632 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013633 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013634 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013635 app.adjType = "home";
13636 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013637
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013638 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13639 && app.activities.size() > 0) {
13640 // This was the previous process that showed UI to the user.
13641 // We want to try to keep it around more aggressively, to give
13642 // a good experience around switching between two apps.
13643 adj = ProcessList.PREVIOUS_APP_ADJ;
13644 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13645 app.hidden = false;
13646 app.adjType = "previous";
13647 }
13648
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013649 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13650 + " reason=" + app.adjType);
13651
The Android Open Source Project4df24232009-03-05 14:34:35 -080013652 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013653 // there are applications dependent on our services or providers, but
13654 // this gives us a baseline and makes sure we don't get into an
13655 // infinite recursion.
13656 app.adjSeq = mAdjSeq;
13657 app.curRawAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013658
Christopher Tate6fa95972009-06-05 18:43:55 -070013659 if (mBackupTarget != null && app == mBackupTarget.app) {
13660 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013661 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013662 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013663 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013664 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013665 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013666 }
13667 }
13668
Dianne Hackborn7d608422011-08-07 16:24:18 -070013669 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013670 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013671 final long now = SystemClock.uptimeMillis();
13672 // This process is more important if the top activity is
13673 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013674 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013675 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013676 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013677 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013678 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013679 // If this process has shown some UI, let it immediately
13680 // go to the LRU list because it may be pretty heavy with
13681 // UI stuff. We'll tag it with a label just to help
13682 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013683 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013684 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013685 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013686 } else {
13687 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13688 // This service has seen some activity within
13689 // recent memory, so we will keep its process ahead
13690 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013691 if (adj > ProcessList.SERVICE_ADJ) {
13692 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013693 app.adjType = "started-services";
13694 app.hidden = false;
13695 }
13696 }
13697 // If we have let the service slide into the background
13698 // state, still have some text describing what it is doing
13699 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013700 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013701 app.adjType = "started-bg-services";
13702 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013703 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013704 // Don't kill this process because it is doing work; it
13705 // has said it is doing work.
13706 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013707 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013708 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013709 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013710 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013711 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013712 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013713 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013714 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013715 // XXX should compute this based on the max of
13716 // all connected clients.
13717 ConnectionRecord cr = clist.get(i);
13718 if (cr.binding.client == app) {
13719 // Binding to ourself is not interesting.
13720 continue;
13721 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013722 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013723 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013724 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013725 int myHiddenAdj = hiddenAdj;
13726 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013727 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013728 myHiddenAdj = client.hiddenAdj;
13729 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013730 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013731 }
13732 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013733 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013734 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013735 String adjType = null;
13736 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
13737 // Not doing bind OOM management, so treat
13738 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013739 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013740 // If this process has shown some UI, let it immediately
13741 // go to the LRU list because it may be pretty heavy with
13742 // UI stuff. We'll tag it with a label just to help
13743 // debug and understand what is going on.
13744 if (adj > clientAdj) {
13745 adjType = "bound-bg-ui-services";
13746 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013747 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013748 clientAdj = adj;
13749 } else {
13750 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
13751 // This service has not seen activity within
13752 // recent memory, so allow it to drop to the
13753 // LRU list if there is no other reason to keep
13754 // it around. We'll also tag it with a label just
13755 // to help debug and undertand what is going on.
13756 if (adj > clientAdj) {
13757 adjType = "bound-bg-services";
13758 }
13759 clientAdj = adj;
13760 }
13761 }
13762 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013763 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013764 // If this process has recently shown UI, and
13765 // the process that is binding to it is less
13766 // important than being visible, then we don't
13767 // care about the binding as much as we care
13768 // about letting this process get into the LRU
13769 // list to be killed and restarted if needed for
13770 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013771 if (app.hasShownUi && app != mHomeProcess
13772 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013773 adjType = "bound-bg-ui-services";
13774 } else {
13775 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
13776 |Context.BIND_IMPORTANT)) != 0) {
13777 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013778 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
13779 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
13780 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13781 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13782 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013783 adj = clientAdj;
13784 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070013785 app.pendingUiClean = true;
13786 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13787 adj = ProcessList.VISIBLE_APP_ADJ;
13788 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013789 }
13790 if (!client.hidden) {
13791 app.hidden = false;
13792 }
13793 if (client.keeping) {
13794 app.keeping = true;
13795 }
13796 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013797 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013798 }
13799 if (adjType != null) {
13800 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013801 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13802 .REASON_SERVICE_IN_USE;
13803 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013804 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013805 app.adjTarget = s.name;
13806 }
13807 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13808 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13809 schedGroup = Process.THREAD_GROUP_DEFAULT;
13810 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013811 }
13812 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013813 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
13814 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013815 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013816 (a.visible || a.state == ActivityState.RESUMED
13817 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013818 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013819 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13820 schedGroup = Process.THREAD_GROUP_DEFAULT;
13821 }
13822 app.hidden = false;
13823 app.adjType = "service";
13824 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13825 .REASON_SERVICE_IN_USE;
13826 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013827 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013828 app.adjTarget = s.name;
13829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013830 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013831 }
13832 }
13833 }
13834 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013835
Dianne Hackborn287952c2010-09-22 22:34:31 -070013836 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013837 // would like to avoid killing it unless it would prevent the current
13838 // application from running. By default we put the process in
13839 // with the rest of the background processes; as we scan through
13840 // its services we may bump it up from there.
13841 if (adj > hiddenAdj) {
13842 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013843 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013844 app.adjType = "bg-services";
13845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013846 }
13847
Dianne Hackborn7d608422011-08-07 16:24:18 -070013848 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013849 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013850 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013851 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013852 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013853 ContentProviderRecord cpr = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013854 if (cpr.clients.size() != 0) {
13855 Iterator<ProcessRecord> kt = cpr.clients.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013856 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013857 ProcessRecord client = kt.next();
The Android Open Source Project10592532009-03-18 17:39:46 -070013858 if (client == app) {
13859 // Being our own client is not interesting.
13860 continue;
13861 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013862 int myHiddenAdj = hiddenAdj;
13863 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013864 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013865 myHiddenAdj = client.hiddenAdj;
13866 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013867 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013868 }
13869 }
13870 int clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013871 client, myHiddenAdj, TOP_APP, true, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013872 if (adj > clientAdj) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013873 if (app.hasShownUi && app != mHomeProcess
13874 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013875 app.adjType = "bg-ui-provider";
13876 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013877 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13878 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013879 app.adjType = "provider";
13880 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013881 if (!client.hidden) {
13882 app.hidden = false;
13883 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013884 if (client.keeping) {
13885 app.keeping = true;
13886 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070013887 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13888 .REASON_PROVIDER_IN_USE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013889 app.adjSource = client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013890 app.adjSourceOom = clientAdj;
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013891 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013892 }
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013893 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13894 schedGroup = Process.THREAD_GROUP_DEFAULT;
13895 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013896 }
13897 }
13898 // If the provider has external (non-framework) process
13899 // dependencies, ensure that its adjustment is at least
13900 // FOREGROUND_APP_ADJ.
13901 if (cpr.externals != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013902 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13903 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013904 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013905 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013906 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013907 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013908 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013909 }
13910 }
13911 }
13912 }
13913
13914 app.curRawAdj = adj;
13915
Joe Onorato8a9b2202010-02-26 18:56:32 -080013916 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013917 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13918 if (adj > app.maxAdj) {
13919 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013920 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013921 schedGroup = Process.THREAD_GROUP_DEFAULT;
13922 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013923 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013924 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013925 app.keeping = true;
13926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013927
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013928 if (app.hasAboveClient) {
13929 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13930 // then we need to drop its adjustment to be lower than the service's
13931 // in order to honor the request. We want to drop it by one adjustment
13932 // level... but there is special meaning applied to various levels so
13933 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013934 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013935 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013936 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13937 adj = ProcessList.VISIBLE_APP_ADJ;
13938 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13939 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13940 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13941 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013942 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013943 adj++;
13944 }
13945 }
13946
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013947 if (adj == ProcessList.SERVICE_ADJ) {
13948 if (doingAll) {
13949 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13950 mNewNumServiceProcs++;
13951 }
13952 if (app.serviceb) {
13953 adj = ProcessList.SERVICE_B_ADJ;
13954 }
13955 } else {
13956 app.serviceb = false;
13957 }
13958
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013959 app.curAdj = adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013960 app.curSchedGroup = schedGroup;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013961
13962 if (hadForegroundActivities != app.foregroundActivities) {
Jeff Sharkey287bd832011-05-28 19:36:26 -070013963 mHandler.obtainMessage(DISPATCH_FOREGROUND_ACTIVITIES_CHANGED, app.pid, app.info.uid,
13964 app.foregroundActivities).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013965 }
13966
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013967 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013968 }
13969
13970 /**
13971 * Ask a given process to GC right now.
13972 */
13973 final void performAppGcLocked(ProcessRecord app) {
13974 try {
13975 app.lastRequestedGc = SystemClock.uptimeMillis();
13976 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013977 if (app.reportLowMemory) {
13978 app.reportLowMemory = false;
13979 app.thread.scheduleLowMemory();
13980 } else {
13981 app.thread.processInBackground();
13982 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013983 }
13984 } catch (Exception e) {
13985 // whatever.
13986 }
13987 }
13988
13989 /**
13990 * Returns true if things are idle enough to perform GCs.
13991 */
Josh Bartel7f208742010-02-25 11:01:44 -060013992 private final boolean canGcNowLocked() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013993 return mParallelBroadcasts.size() == 0
13994 && mOrderedBroadcasts.size() == 0
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013995 && (mSleeping || (mMainStack.mResumedActivity != null &&
13996 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013997 }
13998
13999 /**
14000 * Perform GCs on all processes that are waiting for it, but only
14001 * if things are idle.
14002 */
14003 final void performAppGcsLocked() {
14004 final int N = mProcessesToGc.size();
14005 if (N <= 0) {
14006 return;
14007 }
Josh Bartel7f208742010-02-25 11:01:44 -060014008 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014009 while (mProcessesToGc.size() > 0) {
14010 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014011 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014012 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14013 <= SystemClock.uptimeMillis()) {
14014 // To avoid spamming the system, we will GC processes one
14015 // at a time, waiting a few seconds between each.
14016 performAppGcLocked(proc);
14017 scheduleAppGcsLocked();
14018 return;
14019 } else {
14020 // It hasn't been long enough since we last GCed this
14021 // process... put it in the list to wait for its time.
14022 addProcessToGcListLocked(proc);
14023 break;
14024 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014025 }
14026 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014027
14028 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014029 }
14030 }
14031
14032 /**
14033 * If all looks good, perform GCs on all processes waiting for them.
14034 */
14035 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014036 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014037 performAppGcsLocked();
14038 return;
14039 }
14040 // Still not idle, wait some more.
14041 scheduleAppGcsLocked();
14042 }
14043
14044 /**
14045 * Schedule the execution of all pending app GCs.
14046 */
14047 final void scheduleAppGcsLocked() {
14048 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014049
14050 if (mProcessesToGc.size() > 0) {
14051 // Schedule a GC for the time to the next process.
14052 ProcessRecord proc = mProcessesToGc.get(0);
14053 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14054
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014055 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014056 long now = SystemClock.uptimeMillis();
14057 if (when < (now+GC_TIMEOUT)) {
14058 when = now + GC_TIMEOUT;
14059 }
14060 mHandler.sendMessageAtTime(msg, when);
14061 }
14062 }
14063
14064 /**
14065 * Add a process to the array of processes waiting to be GCed. Keeps the
14066 * list in sorted order by the last GC time. The process can't already be
14067 * on the list.
14068 */
14069 final void addProcessToGcListLocked(ProcessRecord proc) {
14070 boolean added = false;
14071 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14072 if (mProcessesToGc.get(i).lastRequestedGc <
14073 proc.lastRequestedGc) {
14074 added = true;
14075 mProcessesToGc.add(i+1, proc);
14076 break;
14077 }
14078 }
14079 if (!added) {
14080 mProcessesToGc.add(0, proc);
14081 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014082 }
14083
14084 /**
14085 * Set up to ask a process to GC itself. This will either do it
14086 * immediately, or put it on the list of processes to gc the next
14087 * time things are idle.
14088 */
14089 final void scheduleAppGcLocked(ProcessRecord app) {
14090 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014091 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014092 return;
14093 }
14094 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014095 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014096 scheduleAppGcsLocked();
14097 }
14098 }
14099
Dianne Hackborn287952c2010-09-22 22:34:31 -070014100 final void checkExcessivePowerUsageLocked(boolean doKills) {
14101 updateCpuStatsNow();
14102
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014103 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014104 boolean doWakeKills = doKills;
14105 boolean doCpuKills = doKills;
14106 if (mLastPowerCheckRealtime == 0) {
14107 doWakeKills = false;
14108 }
14109 if (mLastPowerCheckUptime == 0) {
14110 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014111 }
14112 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014113 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014114 }
14115 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014116 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14117 final long curUptime = SystemClock.uptimeMillis();
14118 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14119 mLastPowerCheckRealtime = curRealtime;
14120 mLastPowerCheckUptime = curUptime;
14121 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14122 doWakeKills = false;
14123 }
14124 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14125 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014126 }
14127 int i = mLruProcesses.size();
14128 while (i > 0) {
14129 i--;
14130 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014131 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014132 long wtime;
14133 synchronized (stats) {
14134 wtime = stats.getProcessWakeTime(app.info.uid,
14135 app.pid, curRealtime);
14136 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014137 long wtimeUsed = wtime - app.lastWakeTime;
14138 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14139 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014140 StringBuilder sb = new StringBuilder(128);
14141 sb.append("Wake for ");
14142 app.toShortString(sb);
14143 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014144 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014145 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014146 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014147 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014148 sb.append((wtimeUsed*100)/realtimeSince);
14149 sb.append("%)");
14150 Slog.i(TAG, sb.toString());
14151 sb.setLength(0);
14152 sb.append("CPU for ");
14153 app.toShortString(sb);
14154 sb.append(": over ");
14155 TimeUtils.formatDuration(uptimeSince, sb);
14156 sb.append(" used ");
14157 TimeUtils.formatDuration(cputimeUsed, sb);
14158 sb.append(" (");
14159 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014160 sb.append("%)");
14161 Slog.i(TAG, sb.toString());
14162 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014163 // If a process has held a wake lock for more
14164 // than 50% of the time during this period,
14165 // that sounds pad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014166 if (doWakeKills && realtimeSince > 0
14167 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14168 synchronized (stats) {
14169 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14170 realtimeSince, wtimeUsed);
14171 }
14172 Slog.w(TAG, "Excessive wake lock in " + app.processName
14173 + " (pid " + app.pid + "): held " + wtimeUsed
14174 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014175 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14176 app.processName, app.setAdj, "excessive wake lock");
14177 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014178 } else if (doCpuKills && uptimeSince > 0
14179 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14180 synchronized (stats) {
14181 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14182 uptimeSince, cputimeUsed);
14183 }
14184 Slog.w(TAG, "Excessive CPU in " + app.processName
14185 + " (pid " + app.pid + "): used " + cputimeUsed
14186 + " during " + uptimeSince);
14187 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14188 app.processName, app.setAdj, "excessive cpu");
14189 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014190 } else {
14191 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014192 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014193 }
14194 }
14195 }
14196 }
14197
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014198 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014199 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014200 app.hiddenAdj = hiddenAdj;
14201
14202 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014203 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014204 }
14205
Dianne Hackborn287952c2010-09-22 22:34:31 -070014206 final boolean wasKeeping = app.keeping;
14207
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014208 boolean success = true;
14209
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014210 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014211
Jeff Brown10e89712011-07-08 18:52:57 -070014212 if (app.curRawAdj != app.setRawAdj) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070014213 if (false) {
14214 // Removing for now. Forcing GCs is not so useful anymore
14215 // with Dalvik, and the new memory level hint facility is
14216 // better for what we need to do these days.
14217 if (app.curRawAdj > ProcessList.FOREGROUND_APP_ADJ
14218 && app.setRawAdj <= ProcessList.FOREGROUND_APP_ADJ) {
14219 // If this app is transitioning from foreground to
14220 // non-foreground, have it do a gc.
14221 scheduleAppGcLocked(app);
14222 } else if (app.curRawAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14223 && app.setRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14224 // Likewise do a gc when an app is moving in to the
14225 // background (such as a service stopping).
14226 scheduleAppGcLocked(app);
14227 }
Jeff Brown10e89712011-07-08 18:52:57 -070014228 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014229
Jeff Brown10e89712011-07-08 18:52:57 -070014230 if (wasKeeping && !app.keeping) {
14231 // This app is no longer something we want to keep. Note
14232 // its current wake lock time to later know to kill it if
14233 // it is not behaving well.
14234 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14235 synchronized (stats) {
14236 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14237 app.pid, SystemClock.elapsedRealtime());
14238 }
14239 app.lastCpuTime = app.curCpuTime;
14240 }
14241
14242 app.setRawAdj = app.curRawAdj;
14243 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014244
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014245 if (app.curAdj != app.setAdj) {
14246 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014247 if (true || DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
14248 TAG, "Set " + app.pid + " " + app.processName +
14249 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014250 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014251 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014252 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014253 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014254 }
14255 }
14256 if (app.setSchedGroup != app.curSchedGroup) {
14257 app.setSchedGroup = app.curSchedGroup;
14258 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14259 "Setting process group of " + app.processName
14260 + " to " + app.curSchedGroup);
14261 if (app.waitingToKill != null &&
14262 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14263 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14264 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14265 app.processName, app.setAdj, app.waitingToKill);
14266 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014267 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014268 } else {
14269 if (true) {
14270 long oldId = Binder.clearCallingIdentity();
14271 try {
14272 Process.setProcessGroup(app.pid, app.curSchedGroup);
14273 } catch (Exception e) {
14274 Slog.w(TAG, "Failed setting process group of " + app.pid
14275 + " to " + app.curSchedGroup);
14276 e.printStackTrace();
14277 } finally {
14278 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014279 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014280 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014281 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014282 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014283 app.thread.setSchedulingGroup(app.curSchedGroup);
14284 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014285 }
14286 }
14287 }
14288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014289 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014290 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014291 }
14292
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014293 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014294 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014295 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014296 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014297 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014298 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014299 }
14300 }
14301 return resumedActivity;
14302 }
14303
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014304 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014305 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014306 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14307 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014308 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14309 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014310
14311 mAdjSeq++;
14312
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014313 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014314 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14315 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014316 if (nowHidden != wasHidden) {
14317 // Changed to/from hidden state, so apps after it in the LRU
14318 // list may also be changed.
14319 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014320 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014321 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014322 }
14323
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014324 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014325 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014326 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14327
14328 if (false) {
14329 RuntimeException e = new RuntimeException();
14330 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014331 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014332 }
14333
14334 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014335 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014336
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014337 // Let's determine how many processes we have running vs.
14338 // how many slots we have for background processes; we may want
14339 // to put multiple processes in a slot of there are enough of
14340 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014341 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014342 int factor = (mLruProcesses.size()-4)/numSlots;
14343 if (factor < 1) factor = 1;
14344 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014345 int numHidden = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014346
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014347 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014348 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014349 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014350 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014351 while (i > 0) {
14352 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014353 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014354 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014355 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14356 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014357 && app.curAdj == curHiddenAdj) {
14358 step++;
14359 if (step >= factor) {
14360 step = 0;
14361 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014362 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014363 }
14364 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014365 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014366 numHidden++;
14367 if (numHidden > mProcessLimit) {
14368 Slog.i(TAG, "No longer want " + app.processName
14369 + " (pid " + app.pid + "): hidden #" + numHidden);
14370 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14371 app.processName, app.setAdj, "too many background");
14372 app.killedBackground = true;
14373 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014374 }
14375 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014376 }
14377 }
14378
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014379 mNumServiceProcs = mNewNumServiceProcs;
14380
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014381 // Now determine the memory trimming level of background processes.
14382 // Unfortunately we need to start at the back of the list to do this
14383 // properly. We only do this if the number of background apps we
14384 // are managing to keep around is less than half the maximum we desire;
14385 // if we are keeping a good number around, we'll let them use whatever
14386 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014387 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014388 final int N = mLruProcesses.size();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014389 factor = numHidden/3;
14390 int minFactor = 2;
14391 if (mHomeProcess != null) minFactor++;
14392 if (mPreviousProcess != null) minFactor++;
14393 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014394 step = 0;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014395 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014396 for (i=0; i<N; i++) {
14397 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014398 if (app.curAdj >= ProcessList.HOME_APP_ADJ
14399 && app.curAdj != ProcessList.SERVICE_B_ADJ
14400 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014401 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14402 try {
14403 app.thread.scheduleTrimMemory(curLevel);
14404 } catch (RemoteException e) {
14405 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014406 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014407 // For these apps we will also finish their activities
14408 // to help them free memory.
Dianne Hackborn28695e02011-11-02 21:59:51 -070014409 mMainStack.destroyActivitiesLocked(app, false, "trim");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014410 }
14411 }
14412 app.trimMemoryLevel = curLevel;
14413 step++;
14414 if (step >= factor) {
14415 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014416 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14417 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014418 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014419 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14420 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014421 break;
14422 }
14423 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014424 } else if (app.curAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014425 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014426 && app.thread != null) {
14427 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014428 app.thread.scheduleTrimMemory(
14429 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014430 } catch (RemoteException e) {
14431 }
14432 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014433 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014434 } else if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014435 && app.pendingUiClean) {
14436 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14437 && app.thread != null) {
14438 try {
14439 app.thread.scheduleTrimMemory(
14440 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14441 } catch (RemoteException e) {
14442 }
14443 }
14444 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14445 app.pendingUiClean = false;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014446 } else {
14447 app.trimMemoryLevel = 0;
14448 }
14449 }
14450 } else {
14451 final int N = mLruProcesses.size();
14452 for (i=0; i<N; i++) {
14453 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014454 if ((app.curAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014455 && app.pendingUiClean) {
14456 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14457 && app.thread != null) {
14458 try {
14459 app.thread.scheduleTrimMemory(
14460 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14461 } catch (RemoteException e) {
14462 }
14463 }
14464 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14465 app.pendingUiClean = false;
14466 } else {
14467 app.trimMemoryLevel = 0;
14468 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014469 }
14470 }
14471
14472 if (mAlwaysFinishActivities) {
Dianne Hackborn28695e02011-11-02 21:59:51 -070014473 mMainStack.destroyActivitiesLocked(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014475 }
14476
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014477 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014478 synchronized (this) {
14479 int i;
14480
14481 // First remove any unused application processes whose package
14482 // has been removed.
14483 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14484 final ProcessRecord app = mRemovedProcesses.get(i);
14485 if (app.activities.size() == 0
14486 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014487 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014488 TAG, "Exiting empty application process "
14489 + app.processName + " ("
14490 + (app.thread != null ? app.thread.asBinder() : null)
14491 + ")\n");
14492 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014493 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14494 app.processName, app.setAdj, "empty");
14495 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014496 } else {
14497 try {
14498 app.thread.scheduleExit();
14499 } catch (Exception e) {
14500 // Ignore exceptions.
14501 }
14502 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014503 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014504 mRemovedProcesses.remove(i);
14505
14506 if (app.persistent) {
14507 if (app.persistent) {
14508 addAppLocked(app.info);
14509 }
14510 }
14511 }
14512 }
14513
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014514 // Now update the oom adj for all processes.
14515 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014516 }
14517 }
14518
14519 /** This method sends the specified signal to each of the persistent apps */
14520 public void signalPersistentProcesses(int sig) throws RemoteException {
14521 if (sig != Process.SIGNAL_USR1) {
14522 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14523 }
14524
14525 synchronized (this) {
14526 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14527 != PackageManager.PERMISSION_GRANTED) {
14528 throw new SecurityException("Requires permission "
14529 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14530 }
14531
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014532 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14533 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014534 if (r.thread != null && r.persistent) {
14535 Process.sendSignal(r.pid, sig);
14536 }
14537 }
14538 }
14539 }
14540
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014541 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14542 if (proc == null || proc == mProfileProc) {
14543 proc = mProfileProc;
14544 path = mProfileFile;
14545 profileType = mProfileType;
14546 clearProfilerLocked();
14547 }
14548 if (proc == null) {
14549 return;
14550 }
14551 try {
14552 proc.thread.profilerControl(false, path, null, profileType);
14553 } catch (RemoteException e) {
14554 throw new IllegalStateException("Process disappeared");
14555 }
14556 }
14557
14558 private void clearProfilerLocked() {
14559 if (mProfileFd != null) {
14560 try {
14561 mProfileFd.close();
14562 } catch (IOException e) {
14563 }
14564 }
14565 mProfileApp = null;
14566 mProfileProc = null;
14567 mProfileFile = null;
14568 mProfileType = 0;
14569 mAutoStopProfiler = false;
14570 }
14571
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014572 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014573 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014574
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014575 try {
14576 synchronized (this) {
14577 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14578 // its own permission.
14579 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14580 != PackageManager.PERMISSION_GRANTED) {
14581 throw new SecurityException("Requires permission "
14582 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014583 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014584
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014585 if (start && fd == null) {
14586 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014587 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014588
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014589 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014590 if (process != null) {
14591 try {
14592 int pid = Integer.parseInt(process);
14593 synchronized (mPidsSelfLocked) {
14594 proc = mPidsSelfLocked.get(pid);
14595 }
14596 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014597 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014598
14599 if (proc == null) {
14600 HashMap<String, SparseArray<ProcessRecord>> all
14601 = mProcessNames.getMap();
14602 SparseArray<ProcessRecord> procs = all.get(process);
14603 if (procs != null && procs.size() > 0) {
14604 proc = procs.valueAt(0);
14605 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014606 }
14607 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014608
14609 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014610 throw new IllegalArgumentException("Unknown process: " + process);
14611 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014612
14613 if (start) {
14614 stopProfilerLocked(null, null, 0);
14615 setProfileApp(proc.info, proc.processName, path, fd, false);
14616 mProfileProc = proc;
14617 mProfileType = profileType;
14618 try {
14619 fd = fd.dup();
14620 } catch (IOException e) {
14621 fd = null;
14622 }
14623 proc.thread.profilerControl(start, path, fd, profileType);
14624 fd = null;
14625 mProfileFd = null;
14626 } else {
14627 stopProfilerLocked(proc, path, profileType);
14628 if (fd != null) {
14629 try {
14630 fd.close();
14631 } catch (IOException e) {
14632 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014633 }
14634 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014635
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014636 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014637 }
14638 } catch (RemoteException e) {
14639 throw new IllegalStateException("Process disappeared");
14640 } finally {
14641 if (fd != null) {
14642 try {
14643 fd.close();
14644 } catch (IOException e) {
14645 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014646 }
14647 }
14648 }
Andy McFadden824c5102010-07-09 16:26:57 -070014649
14650 public boolean dumpHeap(String process, boolean managed,
14651 String path, ParcelFileDescriptor fd) throws RemoteException {
14652
14653 try {
14654 synchronized (this) {
14655 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14656 // its own permission (same as profileControl).
14657 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14658 != PackageManager.PERMISSION_GRANTED) {
14659 throw new SecurityException("Requires permission "
14660 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14661 }
14662
14663 if (fd == null) {
14664 throw new IllegalArgumentException("null fd");
14665 }
14666
14667 ProcessRecord proc = null;
14668 try {
14669 int pid = Integer.parseInt(process);
14670 synchronized (mPidsSelfLocked) {
14671 proc = mPidsSelfLocked.get(pid);
14672 }
14673 } catch (NumberFormatException e) {
14674 }
14675
14676 if (proc == null) {
14677 HashMap<String, SparseArray<ProcessRecord>> all
14678 = mProcessNames.getMap();
14679 SparseArray<ProcessRecord> procs = all.get(process);
14680 if (procs != null && procs.size() > 0) {
14681 proc = procs.valueAt(0);
14682 }
14683 }
14684
14685 if (proc == null || proc.thread == null) {
14686 throw new IllegalArgumentException("Unknown process: " + process);
14687 }
14688
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014689 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14690 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014691 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14692 throw new SecurityException("Process not debuggable: " + proc);
14693 }
14694 }
14695
14696 proc.thread.dumpHeap(managed, path, fd);
14697 fd = null;
14698 return true;
14699 }
14700 } catch (RemoteException e) {
14701 throw new IllegalStateException("Process disappeared");
14702 } finally {
14703 if (fd != null) {
14704 try {
14705 fd.close();
14706 } catch (IOException e) {
14707 }
14708 }
14709 }
14710 }
14711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014712 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14713 public void monitor() {
14714 synchronized (this) { }
14715 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014716
14717 public void onCoreSettingsChange(Bundle settings) {
14718 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14719 ProcessRecord processRecord = mLruProcesses.get(i);
14720 try {
14721 if (processRecord.thread != null) {
14722 processRecord.thread.setCoreSettings(settings);
14723 }
14724 } catch (RemoteException re) {
14725 /* ignore */
14726 }
14727 }
14728 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014729
14730 // Multi-user methods
14731
14732 public boolean switchUser(int userid) {
14733 // TODO
14734 return true;
14735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014736}