blob: 73deef0dd377d782473cdf627397b4d8793dcef4 [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
Jeff Sharkey110a6b62012-03-12 11:12:41 -070019import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
Dianne Hackborn860755f2010-06-03 18:47:52 -070021import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070023import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070024import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import com.android.server.SystemServer;
28import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070029import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080030import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Dianne Hackborndd71fc82009-12-16 19:24:32 -080032import dalvik.system.Zygote;
33
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070037import android.app.ActivityOptions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.app.ActivityThread;
39import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070040import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020041import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070043import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070046import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070047import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.app.IServiceConnection;
49import android.app.IThumbnailReceiver;
50import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070051import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070052import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.app.PendingIntent;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070054import android.app.Service;
Christopher Tate45281862010-03-05 15:46:30 -080055import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020056import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080057import android.content.BroadcastReceiver;
Dianne Hackborn21c241e2012-03-08 13:57:23 -080058import android.content.ClipData;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070059import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.content.ComponentName;
Jeff Sharkey110a6b62012-03-12 11:12:41 -070061import android.content.ContentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.ContentResolver;
63import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020064import android.content.DialogInterface;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070065import android.content.IContentProvider;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070066import android.content.IIntentReceiver;
67import android.content.IIntentSender;
Adam Powelldd8fab22012-03-22 17:47:27 -070068import android.content.Intent;
69import android.content.IntentFilter;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070070import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.content.pm.ActivityInfo;
72import android.content.pm.ApplicationInfo;
73import android.content.pm.ConfigurationInfo;
74import android.content.pm.IPackageDataObserver;
75import android.content.pm.IPackageManager;
76import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080077import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.content.pm.PackageManager;
Adam Powelldd8fab22012-03-22 17:47:27 -070079import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070080import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.content.pm.ProviderInfo;
82import android.content.pm.ResolveInfo;
83import android.content.pm.ServiceInfo;
Amith Yamasani742a6712011-05-04 14:49:28 -070084import android.content.pm.UserInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040085import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.content.res.Configuration;
87import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070088import android.net.Proxy;
89import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.net.Uri;
91import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080092import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080093import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070094import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080095import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080097import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.os.FileUtils;
99import android.os.Handler;
100import android.os.IBinder;
101import android.os.IPermissionController;
102import android.os.Looper;
103import android.os.Message;
104import android.os.Parcel;
105import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700107import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.os.RemoteException;
rpcraigec7ed14c2012-07-25 13:10:37 -0400109import android.os.SELinux;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700111import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.os.SystemClock;
113import android.os.SystemProperties;
Amith Yamasani742a6712011-05-04 14:49:28 -0700114import android.os.UserId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.provider.Settings;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700116import android.text.format.Time;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117import android.util.EventLog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800118import android.util.Log;
Adam Powelldd8fab22012-03-22 17:47:27 -0700119import android.util.Pair;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120import android.util.PrintWriterPrinter;
Adam Powelldd8fab22012-03-22 17:47:27 -0700121import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800122import android.util.SparseArray;
Amith Yamasani742a6712011-05-04 14:49:28 -0700123import android.util.SparseIntArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700124import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125import android.view.Gravity;
126import android.view.LayoutInflater;
127import android.view.View;
128import android.view.WindowManager;
129import android.view.WindowManagerPolicy;
130
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700131import java.io.BufferedInputStream;
132import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700133import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700134import java.io.DataInputStream;
135import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800136import java.io.File;
137import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700138import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700140import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200141import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800142import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700144import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145import java.lang.ref.WeakReference;
146import java.util.ArrayList;
Amith Yamasani742a6712011-05-04 14:49:28 -0700147import java.util.Collection;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700148import java.util.Collections;
149import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150import java.util.HashMap;
151import java.util.HashSet;
152import java.util.Iterator;
153import java.util.List;
154import java.util.Locale;
155import java.util.Map;
Amith Yamasani13593602012-03-22 16:16:17 -0700156import java.util.Map.Entry;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700157import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700158import java.util.concurrent.atomic.AtomicBoolean;
159import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700161public final class ActivityManagerService extends ActivityManagerNative
162 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
Amith Yamasani742a6712011-05-04 14:49:28 -0700163 private static final String USER_DATA_DIR = "/data/user/";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final String TAG = "ActivityManager";
Amith Yamasani742a6712011-05-04 14:49:28 -0700165 static final String TAG_MU = "ActivityManagerServiceMU";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400167 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static final boolean DEBUG_SWITCH = localLOGV || false;
169 static final boolean DEBUG_TASKS = localLOGV || false;
170 static final boolean DEBUG_PAUSE = localLOGV || false;
171 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
172 static final boolean DEBUG_TRANSITION = localLOGV || false;
173 static final boolean DEBUG_BROADCAST = localLOGV || false;
Christopher Tatef46723b2012-01-26 14:19:24 -0800174 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700175 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700177 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 static final boolean DEBUG_VISBILITY = localLOGV || false;
179 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700180 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700181 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800182 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700184 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700185 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700186 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700187 static final boolean DEBUG_POWER = localLOGV || false;
188 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
Amith Yamasani742a6712011-05-04 14:49:28 -0700189 static final boolean DEBUG_MU = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 static final boolean VALIDATE_TOKENS = false;
191 static final boolean SHOW_ACTIVITY_START_TIME = true;
192
193 // Control over CPU and battery monitoring.
194 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
195 static final boolean MONITOR_CPU_USAGE = true;
196 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
197 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
198 static final boolean MONITOR_THREAD_CPU_USAGE = false;
199
Dianne Hackborn1655be42009-05-08 14:29:01 -0700200 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700201 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700202
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800203 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700205 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 // Maximum number of recent tasks that we can remember.
208 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700209
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700210 // Amount of time after a call to stopAppSwitches() during which we will
211 // prevent further untrusted switches from happening.
212 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213
214 // How long we wait for a launched process to attach to the activity manager
215 // before we decide it's never going to come up for real.
216 static final int PROC_START_TIMEOUT = 10*1000;
217
Jeff Brown3f9dd282011-07-08 20:02:19 -0700218 // How long we wait for a launched process to attach to the activity manager
219 // before we decide it's never going to come up for real, when the process was
220 // started with a wrapper for instrumentation (such as Valgrind) because it
221 // could take much longer than usual.
222 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 // How long to wait after going idle before forcing apps to GC.
225 static final int GC_TIMEOUT = 5*1000;
226
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700227 // The minimum amount of time between successive GC requests for a process.
228 static final int GC_MIN_INTERVAL = 60*1000;
229
Dianne Hackborn287952c2010-09-22 22:34:31 -0700230 // The rate at which we check for apps using excessive power -- 15 mins.
231 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
232
233 // The minimum sample duration we will allow before deciding we have
234 // enough data on wake locks to start killing things.
235 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
236
237 // The minimum sample duration we will allow before deciding we have
238 // enough data on CPU usage to start killing things.
239 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 // How long we allow a receiver to run before giving up on it.
Christopher Tatef46723b2012-01-26 14:19:24 -0800242 static final int BROADCAST_FG_TIMEOUT = 10*1000;
243 static final int BROADCAST_BG_TIMEOUT = 60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244
245 // How long we wait for a service to finish executing.
246 static final int SERVICE_TIMEOUT = 20*1000;
247
248 // How long a service needs to be running until restarting its process
249 // is no longer considered to be a relaunch of the service.
250 static final int SERVICE_RESTART_DURATION = 5*1000;
251
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700252 // How long a service needs to be running until it will start back at
253 // SERVICE_RESTART_DURATION after being killed.
254 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
255
256 // Multiplying factor to increase restart duration time by, for each time
257 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
258 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
259
260 // The minimum amount of time between restarting services that we allow.
261 // That is, when multiple services are restarting, we won't allow each
262 // to restart less than this amount of time from the last one.
263 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
264
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 // Maximum amount of time for there to be no activity on a service before
266 // we consider it non-essential and allow its process to go on the
267 // LRU background list.
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700268 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269
270 // How long we wait until we timeout on key dispatching.
271 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273 // How long we wait until we timeout on key dispatching during instrumentation.
274 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
275
Dan Egnor42471dd2010-01-07 17:25:22 -0800276 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277
278 static final String[] EMPTY_STRING_ARRAY = new String[0];
279
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700280 public ActivityStack mMainStack;
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700281
282 private final boolean mHeadless;
283
Joe Onorato54a4a412011-11-02 20:50:08 -0700284 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
285 // default actuion automatically. Important for devices without direct input
286 // devices.
287 private boolean mShowDialogs = true;
288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700290 * Description of a request to start a new activity, which has been held
291 * due to app switches being disabled.
292 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700293 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700294 ActivityRecord r;
295 ActivityRecord sourceRecord;
Dianne Hackborna4972e92012-03-14 10:38:05 -0700296 int startFlags;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700297 }
298
299 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
300 = new ArrayList<PendingActivityLaunch>();
301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800303 BroadcastQueue mFgBroadcastQueue;
304 BroadcastQueue mBgBroadcastQueue;
Christopher Tatef46723b2012-01-26 14:19:24 -0800305 // Convenient for easy iteration over the queues. Foreground is first
306 // so that dispatch of foreground broadcasts gets precedence.
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800307 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
Christopher Tatef46723b2012-01-26 14:19:24 -0800308
309 BroadcastQueue broadcastQueueForIntent(Intent intent) {
310 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
311 if (DEBUG_BACKGROUND_BROADCAST) {
312 Slog.i(TAG, "Broadcast intent " + intent + " on "
313 + (isFg ? "foreground" : "background")
314 + " queue");
315 }
316 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
317 }
318
319 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
320 for (BroadcastQueue queue : mBroadcastQueues) {
321 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
322 if (r != null) {
323 return r;
324 }
325 }
326 return null;
327 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328
329 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 * Activity we have told the window manager to have key focus.
331 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700332 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700333 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 * List of intents that were used to start the most recent tasks.
335 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700336 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337
338 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700339 * Process management.
340 */
341 final ProcessList mProcessList = new ProcessList();
342
343 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 * All of the applications we currently have running organized by name.
345 * The keys are strings of the application package name (as
346 * returned by the package manager), and the keys are ApplicationRecord
347 * objects.
348 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700349 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350
351 /**
Dianne Hackborna0c283e2012-02-09 10:47:01 -0800352 * The currently running isolated processes.
353 */
354 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
355
356 /**
357 * Counter for assigning isolated process uids, to avoid frequently reusing the
358 * same ones.
359 */
360 int mNextIsolatedProcessUid = 0;
361
362 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700363 * The currently running heavy-weight process, if any.
364 */
365 ProcessRecord mHeavyWeightProcess = null;
366
367 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 * The last time that various processes have crashed.
369 */
370 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
371
372 /**
373 * Set of applications that we consider to be bad, and will reject
374 * incoming broadcasts from (which the user has no control over).
375 * Processes are added to this set when they have crashed twice within
376 * a minimum amount of time; they are removed from it when they are
377 * later restarted (hopefully due to some user action). The value is the
378 * time it was added to the list.
379 */
380 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
381
382 /**
383 * All of the processes we currently have running organized by pid.
384 * The keys are the pid running the application.
385 *
386 * <p>NOTE: This object is protected by its own lock, NOT the global
387 * activity manager lock!
388 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700389 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390
391 /**
392 * All of the processes that have been forced to be foreground. The key
393 * is the pid of the caller who requested it (we hold a death
394 * link on it).
395 */
396 abstract class ForegroundToken implements IBinder.DeathRecipient {
397 int pid;
398 IBinder token;
399 }
400 final SparseArray<ForegroundToken> mForegroundProcesses
401 = new SparseArray<ForegroundToken>();
402
403 /**
404 * List of records for processes that someone had tried to start before the
405 * system was ready. We don't start them at that point, but ensure they
406 * are started by the time booting is complete.
407 */
408 final ArrayList<ProcessRecord> mProcessesOnHold
409 = new ArrayList<ProcessRecord>();
410
411 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800412 * List of persistent applications that are in the process
413 * of being started.
414 */
415 final ArrayList<ProcessRecord> mPersistentStartingProcesses
416 = new ArrayList<ProcessRecord>();
417
418 /**
419 * Processes that are being forcibly torn down.
420 */
421 final ArrayList<ProcessRecord> mRemovedProcesses
422 = new ArrayList<ProcessRecord>();
423
424 /**
425 * List of running applications, sorted by recent usage.
426 * The first entry in the list is the least recently used.
427 * It contains ApplicationRecord objects. This list does NOT include
428 * any persistent application records (since we never want to exit them).
429 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800430 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800431 = new ArrayList<ProcessRecord>();
432
433 /**
434 * List of processes that should gc as soon as things are idle.
435 */
436 final ArrayList<ProcessRecord> mProcessesToGc
437 = new ArrayList<ProcessRecord>();
438
439 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800440 * This is the process holding what we currently consider to be
441 * the "home" activity.
442 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700443 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800444
445 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700446 * This is the process holding the activity the user last visited that
447 * is in a different process from the one they are currently in.
448 */
449 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -0800450
451 /**
452 * The time at which the previous process was last visible.
453 */
454 long mPreviousProcessVisibleTime;
455
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700456 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400457 * Packages that the user has asked to have run in screen size
458 * compatibility mode instead of filling the screen.
459 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700460 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400461
462 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800463 * Set of PendingResultRecord objects that are currently active.
464 */
465 final HashSet mPendingResultRecords = new HashSet();
466
467 /**
468 * Set of IntentSenderRecord objects that are currently active.
469 */
470 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
471 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
472
473 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800474 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700475 * already logged DropBox entries for. Guarded by itself. If
476 * something (rogue user app) forces this over
477 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
478 */
479 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
480 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
481
482 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700483 * Strict Mode background batched logging state.
484 *
485 * The string buffer is guarded by itself, and its lock is also
486 * used to determine if another batched write is already
487 * in-flight.
488 */
489 private final StringBuilder mStrictModeBuffer = new StringBuilder();
490
491 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800492 * Keeps track of all IIntentReceivers that have been registered for
493 * broadcasts. Hash keys are the receiver IBinder, hash value is
494 * a ReceiverList.
495 */
496 final HashMap mRegisteredReceivers = new HashMap();
497
498 /**
499 * Resolver for broadcast intents to registered receivers.
500 * Holds BroadcastFilter (subclass of IntentFilter).
501 */
502 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
503 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
504 @Override
505 protected boolean allowFilterResult(
506 BroadcastFilter filter, List<BroadcastFilter> dest) {
507 IBinder target = filter.receiverList.receiver.asBinder();
508 for (int i=dest.size()-1; i>=0; i--) {
509 if (dest.get(i).receiverList.receiver.asBinder() == target) {
510 return false;
511 }
512 }
513 return true;
514 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700515
516 @Override
517 protected String packageForFilter(BroadcastFilter filter) {
518 return filter.packageName;
519 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800520 };
521
522 /**
523 * State of all active sticky broadcasts. Keys are the action of the
524 * sticky Intent, values are an ArrayList of all broadcasted intents with
525 * that action (which should usually be one).
526 */
527 final HashMap<String, ArrayList<Intent>> mStickyBroadcasts =
528 new HashMap<String, ArrayList<Intent>>();
529
Amith Yamasani742a6712011-05-04 14:49:28 -0700530 final ServiceMap mServiceMap = new ServiceMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800531
532 /**
533 * All currently bound service connections. Keys are the IBinder of
534 * the client's IServiceConnection.
535 */
Dianne Hackborn43d9ac82010-08-25 15:06:25 -0700536 final HashMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
537 = new HashMap<IBinder, ArrayList<ConnectionRecord>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800538
539 /**
540 * List of services that we have been asked to start,
541 * but haven't yet been able to. It is used to hold start requests
542 * while waiting for their corresponding application thread to get
543 * going.
544 */
545 final ArrayList<ServiceRecord> mPendingServices
546 = new ArrayList<ServiceRecord>();
547
548 /**
549 * List of services that are scheduled to restart following a crash.
550 */
551 final ArrayList<ServiceRecord> mRestartingServices
552 = new ArrayList<ServiceRecord>();
553
554 /**
555 * List of services that are in the process of being stopped.
556 */
557 final ArrayList<ServiceRecord> mStoppingServices
558 = new ArrayList<ServiceRecord>();
559
560 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700561 * Backup/restore process management
562 */
563 String mBackupAppName = null;
564 BackupRecord mBackupTarget = null;
565
566 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800567 * List of PendingThumbnailsRecord objects of clients who are still
568 * waiting to receive all of the thumbnails for a task.
569 */
570 final ArrayList mPendingThumbnails = new ArrayList();
571
572 /**
573 * List of HistoryRecord objects that have been finished and must
574 * still report back to a pending thumbnail receiver.
575 */
576 final ArrayList mCancelledThumbnails = new ArrayList();
577
Amith Yamasani742a6712011-05-04 14:49:28 -0700578 final ProviderMap mProviderMap = new ProviderMap();
579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 /**
581 * List of content providers who have clients waiting for them. The
582 * application is currently being launched and the provider will be
583 * removed from this list once it is published.
584 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700585 final ArrayList<ContentProviderRecord> mLaunchingProviders
586 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587
588 /**
589 * Global set of specific Uri permissions that have been granted.
590 */
591 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
592 = new SparseArray<HashMap<Uri, UriPermission>>();
593
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800594 CoreSettingsObserver mCoreSettingsObserver;
595
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 /**
597 * Thread-local storage used to carry caller permissions over through
598 * indirect content-provider access.
599 * @see #ActivityManagerService.openContentUri()
600 */
601 private class Identity {
602 public int pid;
603 public int uid;
604
605 Identity(int _pid, int _uid) {
606 pid = _pid;
607 uid = _uid;
608 }
609 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
612
613 /**
614 * All information we have collected about the runtime performance of
615 * any user id that can impact battery performance.
616 */
617 final BatteryStatsService mBatteryStatsService;
618
619 /**
620 * information about component usage
621 */
622 final UsageStatsService mUsageStatsService;
623
624 /**
625 * Current configuration information. HistoryRecord objects are given
626 * a reference to this object to indicate which configuration they are
627 * currently running in, so this object must be kept immutable.
628 */
629 Configuration mConfiguration = new Configuration();
630
631 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800632 * Current sequencing integer of the configuration, for skipping old
633 * configurations.
634 */
635 int mConfigurationSeq = 0;
636
637 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700638 * Hardware-reported OpenGLES version.
639 */
640 final int GL_ES_VERSION;
641
642 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800643 * List of initialization arguments to pass to all processes when binding applications to them.
644 * For example, references to the commonly used services.
645 */
646 HashMap<String, IBinder> mAppBindArgs;
647
648 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700649 * Temporary to avoid allocations. Protected by main lock.
650 */
651 final StringBuilder mStringBuilder = new StringBuilder(256);
652
653 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 * Used to control how we initialize the service.
655 */
656 boolean mStartRunning = false;
657 ComponentName mTopComponent;
658 String mTopAction;
659 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700660 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800661 boolean mSystemReady = false;
662 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700663 boolean mWaitingUpdate = false;
664 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700665 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700666 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667
668 Context mContext;
669
670 int mFactoryTest;
671
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700672 boolean mCheckedForSetup;
673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700675 * The time at which we will allow normal application switches again,
676 * after a call to {@link #stopAppSwitches()}.
677 */
678 long mAppSwitchesAllowedTime;
679
680 /**
681 * This is set to true after the first switch after mAppSwitchesAllowedTime
682 * is set; any switches after that will clear the time.
683 */
684 boolean mDidAppSwitch;
685
686 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700687 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700688 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700689 long mLastPowerCheckRealtime;
690
691 /**
692 * Last time (in uptime) at which we checked for power usage.
693 */
694 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700695
696 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800697 * Set while we are wanting to sleep, to prevent any
698 * activities from being started/resumed.
699 */
700 boolean mSleeping = false;
701
702 /**
Dianne Hackbornff5b1582012-04-12 17:24:07 -0700703 * State of external calls telling us if the device is asleep.
704 */
705 boolean mWentToSleep = false;
706
707 /**
708 * State of external call telling us if the lock screen is shown.
709 */
710 boolean mLockScreenShown = false;
711
712 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700713 * Set if we are shutting down the system, similar to sleeping.
714 */
715 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716
717 /**
718 * Task identifier that activities are currently being started
719 * in. Incremented each time a new task is created.
720 * todo: Replace this with a TokenSpace class that generates non-repeating
721 * integers that won't wrap.
722 */
723 int mCurTask = 1;
724
725 /**
726 * Current sequence id for oom_adj computation traversal.
727 */
728 int mAdjSeq = 0;
729
730 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700731 * Current sequence id for process LRU updating.
732 */
733 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734
735 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700736 * Keep track of the number of service processes we last found, to
737 * determine on the next iteration which should be B services.
738 */
739 int mNumServiceProcs = 0;
740 int mNewNumServiceProcs = 0;
741
742 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 * System monitoring: number of processes that died since the last
744 * N procs were started.
745 */
746 int[] mProcDeaths = new int[20];
747
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700748 /**
749 * This is set if we had to do a delayed dexopt of an app before launching
750 * it, to increasing the ANR timeouts in that case.
751 */
752 boolean mDidDexOpt;
753
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 String mDebugApp = null;
755 boolean mWaitForDebugger = false;
756 boolean mDebugTransient = false;
757 String mOrigDebugApp = null;
758 boolean mOrigWaitForDebugger = false;
759 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700760 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700761 String mProfileApp = null;
762 ProcessRecord mProfileProc = null;
763 String mProfileFile;
764 ParcelFileDescriptor mProfileFd;
765 int mProfileType = 0;
766 boolean mAutoStopProfiler = false;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800767 String mOpenGlTraceApp = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700769 static class ProcessChangeItem {
770 static final int CHANGE_ACTIVITIES = 1<<0;
771 static final int CHANGE_IMPORTANCE= 1<<1;
772 int changes;
773 int uid;
774 int pid;
775 int importance;
776 boolean foregroundActivities;
777 }
778
Jeff Sharkeya4620792011-05-20 15:29:23 -0700779 final RemoteCallbackList<IProcessObserver> mProcessObservers
780 = new RemoteCallbackList<IProcessObserver>();
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700781 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
782
783 final ArrayList<ProcessChangeItem> mPendingProcessChanges
784 = new ArrayList<ProcessChangeItem>();
785 final ArrayList<ProcessChangeItem> mAvailProcessChanges
786 = new ArrayList<ProcessChangeItem>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 /**
789 * Callback of last caller to {@link #requestPss}.
790 */
791 Runnable mRequestPssCallback;
792
793 /**
794 * Remaining processes for which we are waiting results from the last
795 * call to {@link #requestPss}.
796 */
797 final ArrayList<ProcessRecord> mRequestPssList
798 = new ArrayList<ProcessRecord>();
799
800 /**
801 * Runtime statistics collection thread. This object's lock is used to
802 * protect all related state.
803 */
804 final Thread mProcessStatsThread;
805
806 /**
807 * Used to collect process stats when showing not responding dialog.
808 * Protected by mProcessStatsThread.
809 */
810 final ProcessStats mProcessStats = new ProcessStats(
811 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700812 final AtomicLong mLastCpuTime = new AtomicLong(0);
813 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800815 long mLastWriteTime = 0;
816
817 /**
818 * Set to true after the system has finished booting.
819 */
820 boolean mBooted = false;
821
Dianne Hackborn7d608422011-08-07 16:24:18 -0700822 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700823 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824
825 WindowManagerService mWindowManager;
826
827 static ActivityManagerService mSelf;
828 static ActivityThread mSystemThread;
829
830 private final class AppDeathRecipient implements IBinder.DeathRecipient {
831 final ProcessRecord mApp;
832 final int mPid;
833 final IApplicationThread mAppThread;
834
835 AppDeathRecipient(ProcessRecord app, int pid,
836 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800837 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 TAG, "New death recipient " + this
839 + " for thread " + thread.asBinder());
840 mApp = app;
841 mPid = pid;
842 mAppThread = thread;
843 }
844
845 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800846 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 TAG, "Death received in " + this
848 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 synchronized(ActivityManagerService.this) {
850 appDiedLocked(mApp, mPid, mAppThread);
851 }
852 }
853 }
854
855 static final int SHOW_ERROR_MSG = 1;
856 static final int SHOW_NOT_RESPONDING_MSG = 2;
857 static final int SHOW_FACTORY_ERROR_MSG = 3;
858 static final int UPDATE_CONFIGURATION_MSG = 4;
859 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
860 static final int WAIT_FOR_DEBUGGER_MSG = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 static final int SERVICE_TIMEOUT_MSG = 12;
862 static final int UPDATE_TIME_ZONE = 13;
863 static final int SHOW_UID_ERROR_MSG = 14;
864 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800865 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700866 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700867 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800868 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700869 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
870 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700871 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700872 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700873 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700874 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700875 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700876 static final int DISPATCH_PROCESSES_CHANGED = 31;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700877 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700878 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800879
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800880 static final int FIRST_ACTIVITY_STACK_MSG = 100;
881 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
882 static final int FIRST_COMPAT_MODE_MSG = 300;
883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700885 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700886 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887
888 final Handler mHandler = new Handler() {
889 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800890 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800891 //}
892
893 public void handleMessage(Message msg) {
894 switch (msg.what) {
895 case SHOW_ERROR_MSG: {
896 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800897 synchronized (ActivityManagerService.this) {
898 ProcessRecord proc = (ProcessRecord)data.get("app");
899 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800900 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800901 return;
902 }
903 AppErrorResult res = (AppErrorResult) data.get("result");
Joe Onorato54a4a412011-11-02 20:50:08 -0700904 if (mShowDialogs && !mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800905 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 d.show();
907 proc.crashDialog = d;
908 } else {
909 // The device is asleep, so just pretend that the user
910 // saw a crash dialog and hit "force quit".
911 res.set(0);
912 }
913 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700914
915 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 } break;
917 case SHOW_NOT_RESPONDING_MSG: {
918 synchronized (ActivityManagerService.this) {
919 HashMap data = (HashMap) msg.obj;
920 ProcessRecord proc = (ProcessRecord)data.get("app");
921 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800922 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 return;
924 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800925
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700926 Intent intent = new Intent("android.intent.action.ANR");
927 if (!mProcessesReady) {
Christopher Tatef46723b2012-01-26 14:19:24 -0800928 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
929 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700930 }
931 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800932 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700933 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800934
Justin Kohbc52ca22012-03-29 15:11:44 -0700935 if (mShowDialogs) {
936 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Mike Lockwood69ccdbd2012-04-03 11:53:47 -0700937 mContext, proc, (ActivityRecord)data.get("activity"));
Justin Kohbc52ca22012-03-29 15:11:44 -0700938 d.show();
939 proc.anrDialog = d;
940 } else {
941 // Just kill the app if there is no dialog to be shown.
942 killAppAtUsersRequest(proc, null);
943 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700945
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700946 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800947 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700948 case SHOW_STRICT_MODE_VIOLATION_MSG: {
949 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
950 synchronized (ActivityManagerService.this) {
951 ProcessRecord proc = (ProcessRecord) data.get("app");
952 if (proc == null) {
953 Slog.e(TAG, "App not found when showing strict mode dialog.");
954 break;
955 }
956 if (proc.crashDialog != null) {
957 Slog.e(TAG, "App already has strict mode dialog: " + proc);
958 return;
959 }
960 AppErrorResult res = (AppErrorResult) data.get("result");
Joe Onorato54a4a412011-11-02 20:50:08 -0700961 if (mShowDialogs && !mSleeping && !mShuttingDown) {
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700962 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
963 d.show();
964 proc.crashDialog = d;
965 } else {
966 // The device is asleep, so just pretend that the user
967 // saw a crash dialog and hit "force quit".
968 res.set(0);
969 }
970 }
971 ensureBootCompleted();
972 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 case SHOW_FACTORY_ERROR_MSG: {
974 Dialog d = new FactoryErrorDialog(
975 mContext, msg.getData().getCharSequence("msg"));
976 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700977 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 } break;
979 case UPDATE_CONFIGURATION_MSG: {
980 final ContentResolver resolver = mContext.getContentResolver();
981 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
982 } break;
983 case GC_BACKGROUND_PROCESSES_MSG: {
984 synchronized (ActivityManagerService.this) {
985 performAppGcsIfAppropriateLocked();
986 }
987 } break;
988 case WAIT_FOR_DEBUGGER_MSG: {
989 synchronized (ActivityManagerService.this) {
990 ProcessRecord app = (ProcessRecord)msg.obj;
991 if (msg.arg1 != 0) {
992 if (!app.waitedForDebugger) {
993 Dialog d = new AppWaitingForDebuggerDialog(
994 ActivityManagerService.this,
995 mContext, app);
996 app.waitDialog = d;
997 app.waitedForDebugger = true;
998 d.show();
999 }
1000 } else {
1001 if (app.waitDialog != null) {
1002 app.waitDialog.dismiss();
1003 app.waitDialog = null;
1004 }
1005 }
1006 }
1007 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001009 if (mDidDexOpt) {
1010 mDidDexOpt = false;
1011 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1012 nmsg.obj = msg.obj;
1013 mHandler.sendMessageDelayed(nmsg, SERVICE_TIMEOUT);
1014 return;
1015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 serviceTimeout((ProcessRecord)msg.obj);
1017 } break;
1018 case UPDATE_TIME_ZONE: {
1019 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001020 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1021 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 if (r.thread != null) {
1023 try {
1024 r.thread.updateTimeZone();
1025 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001026 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 }
1028 }
1029 }
1030 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001031 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001032 case CLEAR_DNS_CACHE: {
1033 synchronized (ActivityManagerService.this) {
1034 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1035 ProcessRecord r = mLruProcesses.get(i);
1036 if (r.thread != null) {
1037 try {
1038 r.thread.clearDnsCache();
1039 } catch (RemoteException ex) {
1040 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1041 }
1042 }
1043 }
1044 }
1045 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001046 case UPDATE_HTTP_PROXY: {
1047 ProxyProperties proxy = (ProxyProperties)msg.obj;
1048 String host = "";
1049 String port = "";
1050 String exclList = "";
1051 if (proxy != null) {
1052 host = proxy.getHost();
1053 port = Integer.toString(proxy.getPort());
1054 exclList = proxy.getExclusionList();
1055 }
1056 synchronized (ActivityManagerService.this) {
1057 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1058 ProcessRecord r = mLruProcesses.get(i);
1059 if (r.thread != null) {
1060 try {
1061 r.thread.setHttpProxy(host, port, exclList);
1062 } catch (RemoteException ex) {
1063 Slog.w(TAG, "Failed to update http proxy for: " +
1064 r.info.processName);
1065 }
1066 }
1067 }
1068 }
1069 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 case SHOW_UID_ERROR_MSG: {
Joe Onorato54a4a412011-11-02 20:50:08 -07001071 String title = "System UIDs Inconsistent";
1072 String text = "UIDs on the system are inconsistent, you need to wipe your"
1073 + " data partition or your device will be unstable.";
1074 Log.e(TAG, title + ": " + text);
1075 if (mShowDialogs) {
1076 // XXX This is a temporary dialog, no need to localize.
1077 AlertDialog d = new BaseErrorDialog(mContext);
1078 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1079 d.setCancelable(false);
1080 d.setTitle(title);
1081 d.setMessage(text);
1082 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1083 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1084 mUidAlert = d;
1085 d.show();
1086 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001087 } break;
1088 case IM_FEELING_LUCKY_MSG: {
1089 if (mUidAlert != null) {
1090 mUidAlert.dismiss();
1091 mUidAlert = null;
1092 }
1093 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001095 if (mDidDexOpt) {
1096 mDidDexOpt = false;
1097 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1098 nmsg.obj = msg.obj;
1099 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1100 return;
1101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001102 ProcessRecord app = (ProcessRecord)msg.obj;
1103 synchronized (ActivityManagerService.this) {
1104 processStartTimedOutLocked(app);
1105 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001106 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001107 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1108 synchronized (ActivityManagerService.this) {
1109 doPendingActivityLaunchesLocked(true);
1110 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001111 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001112 case KILL_APPLICATION_MSG: {
1113 synchronized (ActivityManagerService.this) {
1114 int uid = msg.arg1;
1115 boolean restart = (msg.arg2 == 1);
1116 String pkg = (String) msg.obj;
Amith Yamasani483f3b02012-03-13 16:08:00 -07001117 forceStopPackageLocked(pkg, uid, restart, false, true, false,
1118 UserId.getUserId(uid));
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001119 }
1120 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001121 case FINALIZE_PENDING_INTENT_MSG: {
1122 ((PendingIntentRecord)msg.obj).completeFinalize();
1123 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001124 case POST_HEAVY_NOTIFICATION_MSG: {
1125 INotificationManager inm = NotificationManager.getService();
1126 if (inm == null) {
1127 return;
1128 }
1129
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001130 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001131 ProcessRecord process = root.app;
1132 if (process == null) {
1133 return;
1134 }
1135
1136 try {
1137 Context context = mContext.createPackageContext(process.info.packageName, 0);
1138 String text = mContext.getString(R.string.heavy_weight_notification,
1139 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1140 Notification notification = new Notification();
1141 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1142 notification.when = 0;
1143 notification.flags = Notification.FLAG_ONGOING_EVENT;
1144 notification.tickerText = text;
1145 notification.defaults = 0; // please be quiet
1146 notification.sound = null;
1147 notification.vibrate = null;
1148 notification.setLatestEventInfo(context, text,
1149 mContext.getText(R.string.heavy_weight_notification_detail),
1150 PendingIntent.getActivity(mContext, 0, root.intent,
1151 PendingIntent.FLAG_CANCEL_CURRENT));
1152
1153 try {
1154 int[] outId = new int[1];
1155 inm.enqueueNotification("android", R.string.heavy_weight_notification,
1156 notification, outId);
1157 } catch (RuntimeException e) {
1158 Slog.w(ActivityManagerService.TAG,
1159 "Error showing notification for heavy-weight app", e);
1160 } catch (RemoteException e) {
1161 }
1162 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001163 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001164 }
1165 } break;
1166 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1167 INotificationManager inm = NotificationManager.getService();
1168 if (inm == null) {
1169 return;
1170 }
1171 try {
1172 inm.cancelNotification("android",
1173 R.string.heavy_weight_notification);
1174 } catch (RuntimeException e) {
1175 Slog.w(ActivityManagerService.TAG,
1176 "Error canceling notification for service", e);
1177 } catch (RemoteException e) {
1178 }
1179 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001180 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1181 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001182 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001183 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001184 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1185 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001186 }
1187 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001188 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1189 synchronized (ActivityManagerService.this) {
1190 ActivityRecord ar = (ActivityRecord)msg.obj;
1191 if (mCompatModeDialog != null) {
1192 if (mCompatModeDialog.mAppInfo.packageName.equals(
1193 ar.info.applicationInfo.packageName)) {
1194 return;
1195 }
1196 mCompatModeDialog.dismiss();
1197 mCompatModeDialog = null;
1198 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001199 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001200 if (mCompatModePackages.getPackageAskCompatModeLocked(
1201 ar.packageName)) {
1202 int mode = mCompatModePackages.computeCompatModeLocked(
1203 ar.info.applicationInfo);
1204 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1205 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1206 mCompatModeDialog = new CompatModeDialog(
1207 ActivityManagerService.this, mContext,
1208 ar.info.applicationInfo);
1209 mCompatModeDialog.show();
1210 }
1211 }
1212 }
1213 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001214 break;
1215 }
Dianne Hackborna93c2c12012-05-31 15:29:36 -07001216 case DISPATCH_PROCESSES_CHANGED: {
1217 dispatchProcessesChanged();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001218 break;
1219 }
1220 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001221 final int pid = msg.arg1;
1222 final int uid = msg.arg2;
1223 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001224 break;
1225 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001226 case REPORT_MEM_USAGE: {
1227 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1228 if (!isDebuggable) {
1229 return;
1230 }
1231 synchronized (ActivityManagerService.this) {
1232 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001233 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1234 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001235 // avoid spamming.
1236 return;
1237 }
1238 mLastMemUsageReportTime = now;
1239 }
1240 Thread thread = new Thread() {
1241 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001242 StringBuilder dropBuilder = new StringBuilder(1024);
1243 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001244 StringWriter oomSw = new StringWriter();
1245 PrintWriter oomPw = new PrintWriter(oomSw);
1246 StringWriter catSw = new StringWriter();
1247 PrintWriter catPw = new PrintWriter(catSw);
1248 String[] emptyArgs = new String[] { };
1249 StringBuilder tag = new StringBuilder(128);
1250 StringBuilder stack = new StringBuilder(128);
1251 tag.append("Low on memory -- ");
1252 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1253 tag, stack);
1254 dropBuilder.append(stack);
1255 dropBuilder.append('\n');
1256 dropBuilder.append('\n');
1257 String oomString = oomSw.toString();
1258 dropBuilder.append(oomString);
1259 dropBuilder.append('\n');
1260 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001261 try {
1262 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1263 "procrank", });
1264 final InputStreamReader converter = new InputStreamReader(
1265 proc.getInputStream());
1266 BufferedReader in = new BufferedReader(converter);
1267 String line;
1268 while (true) {
1269 line = in.readLine();
1270 if (line == null) {
1271 break;
1272 }
1273 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001274 logBuilder.append(line);
1275 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001276 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001277 dropBuilder.append(line);
1278 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001279 }
1280 converter.close();
1281 } catch (IOException e) {
1282 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001283 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001284 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001285 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001286 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001287 dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001288 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001289 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001290 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001291 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001292 addErrorToDropBox("lowmem", null, "system_server", null,
1293 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001294 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001295 synchronized (ActivityManagerService.this) {
1296 long now = SystemClock.uptimeMillis();
1297 if (mLastMemUsageReportTime < now) {
1298 mLastMemUsageReportTime = now;
1299 }
1300 }
1301 }
1302 };
1303 thread.start();
1304 break;
1305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 }
1307 }
1308 };
1309
1310 public static void setSystemProcess() {
1311 try {
1312 ActivityManagerService m = mSelf;
1313
Dianne Hackborna573f6a2012-02-09 16:12:18 -08001314 ServiceManager.addService("activity", m, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001316 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
Jeff Brown6754ba22011-12-14 20:20:01 -08001317 ServiceManager.addService("dbinfo", new DbBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 if (MONITOR_CPU_USAGE) {
1319 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 ServiceManager.addService("permission", new PermissionController(m));
1322
1323 ApplicationInfo info =
1324 mSelf.mContext.getPackageManager().getApplicationInfo(
Amith Yamasani483f3b02012-03-13 16:08:00 -07001325 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001326 mSystemThread.installSystemApplicationInfo(info);
1327
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 synchronized (mSelf) {
1329 ProcessRecord app = mSelf.newProcessRecordLocked(
1330 mSystemThread.getApplicationThread(), info,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001331 info.processName, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001333 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001334 app.maxAdj = ProcessList.SYSTEM_ADJ;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001335 mSelf.mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 synchronized (mSelf.mPidsSelfLocked) {
1337 mSelf.mPidsSelfLocked.put(app.pid, app);
1338 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001339 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 }
1341 } catch (PackageManager.NameNotFoundException e) {
1342 throw new RuntimeException(
1343 "Unable to find android system package", e);
1344 }
1345 }
1346
1347 public void setWindowManager(WindowManagerService wm) {
1348 mWindowManager = wm;
1349 }
1350
1351 public static final Context main(int factoryTest) {
1352 AThread thr = new AThread();
1353 thr.start();
1354
1355 synchronized (thr) {
1356 while (thr.mService == null) {
1357 try {
1358 thr.wait();
1359 } catch (InterruptedException e) {
1360 }
1361 }
1362 }
1363
1364 ActivityManagerService m = thr.mService;
1365 mSelf = m;
1366 ActivityThread at = ActivityThread.systemMain();
1367 mSystemThread = at;
1368 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001369 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 m.mContext = context;
1371 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001372 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373
1374 m.mBatteryStatsService.publish(context);
1375 m.mUsageStatsService.publish(context);
1376
1377 synchronized (thr) {
1378 thr.mReady = true;
1379 thr.notifyAll();
1380 }
1381
1382 m.startRunning(null, null, null, null);
1383
1384 return context;
1385 }
1386
1387 public static ActivityManagerService self() {
1388 return mSelf;
1389 }
1390
1391 static class AThread extends Thread {
1392 ActivityManagerService mService;
1393 boolean mReady = false;
1394
1395 public AThread() {
1396 super("ActivityManager");
1397 }
1398
1399 public void run() {
1400 Looper.prepare();
1401
1402 android.os.Process.setThreadPriority(
1403 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001404 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405
1406 ActivityManagerService m = new ActivityManagerService();
1407
1408 synchronized (this) {
1409 mService = m;
1410 notifyAll();
1411 }
1412
1413 synchronized (this) {
1414 while (!mReady) {
1415 try {
1416 wait();
1417 } catch (InterruptedException e) {
1418 }
1419 }
1420 }
1421
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001422 // For debug builds, log event loop stalls to dropbox for analysis.
1423 if (StrictMode.conditionallyEnableDebugLogging()) {
1424 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1425 }
1426
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 Looper.loop();
1428 }
1429 }
1430
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 static class MemBinder extends Binder {
1432 ActivityManagerService mActivityManagerService;
1433 MemBinder(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 meminfo from from pid="
1442 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1443 + " without permission " + android.Manifest.permission.DUMP);
1444 return;
1445 }
1446
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001447 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001448 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 }
1450 }
1451
Chet Haase9c1e23b2011-03-24 10:51:31 -07001452 static class GraphicsBinder extends Binder {
1453 ActivityManagerService mActivityManagerService;
1454 GraphicsBinder(ActivityManagerService activityManagerService) {
1455 mActivityManagerService = activityManagerService;
1456 }
1457
1458 @Override
1459 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001460 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1461 != PackageManager.PERMISSION_GRANTED) {
1462 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1463 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1464 + " without permission " + android.Manifest.permission.DUMP);
1465 return;
1466 }
1467
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001468 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001469 }
1470 }
1471
Jeff Brown6754ba22011-12-14 20:20:01 -08001472 static class DbBinder extends Binder {
1473 ActivityManagerService mActivityManagerService;
1474 DbBinder(ActivityManagerService activityManagerService) {
1475 mActivityManagerService = activityManagerService;
1476 }
1477
1478 @Override
1479 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1480 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1481 != PackageManager.PERMISSION_GRANTED) {
1482 pw.println("Permission Denial: can't dump dbinfo from from pid="
1483 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1484 + " without permission " + android.Manifest.permission.DUMP);
1485 return;
1486 }
1487
1488 mActivityManagerService.dumpDbInfo(fd, pw, args);
1489 }
1490 }
1491
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492 static class CpuBinder extends Binder {
1493 ActivityManagerService mActivityManagerService;
1494 CpuBinder(ActivityManagerService activityManagerService) {
1495 mActivityManagerService = activityManagerService;
1496 }
1497
1498 @Override
1499 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001500 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1501 != PackageManager.PERMISSION_GRANTED) {
1502 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1503 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1504 + " without permission " + android.Manifest.permission.DUMP);
1505 return;
1506 }
1507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001509 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1510 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1511 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 }
1513 }
1514 }
1515
1516 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001517 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001518
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001519 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1520 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1521 mBroadcastQueues[0] = mFgBroadcastQueue;
1522 mBroadcastQueues[1] = mBgBroadcastQueue;
1523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001524 File dataDir = Environment.getDataDirectory();
1525 File systemDir = new File(dataDir, "system");
1526 systemDir.mkdirs();
1527 mBatteryStatsService = new BatteryStatsService(new File(
1528 systemDir, "batterystats.bin").toString());
1529 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001530 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001531 mOnBattery = DEBUG_POWER ? true
1532 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001533 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001535 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001536 systemDir, "usagestats").toString());
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001537 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001538
Jack Palevichb90d28c2009-07-22 15:35:24 -07001539 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1540 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1541
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001542 mConfiguration.setToDefaults();
1543 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001544 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 mProcessStats.init();
1546
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001547 mCompatModePackages = new CompatModePackages(this, systemDir);
1548
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549 // Add ourself to the Watchdog monitors.
1550 Watchdog.getInstance().addMonitor(this);
1551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001552 mProcessStatsThread = new Thread("ProcessStats") {
1553 public void run() {
1554 while (true) {
1555 try {
1556 try {
1557 synchronized(this) {
1558 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001559 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001561 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 // + ", write delay=" + nextWriteDelay);
1563 if (nextWriteDelay < nextCpuDelay) {
1564 nextCpuDelay = nextWriteDelay;
1565 }
1566 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001567 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001568 this.wait(nextCpuDelay);
1569 }
1570 }
1571 } catch (InterruptedException e) {
1572 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 updateCpuStatsNow();
1574 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001575 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 }
1577 }
1578 }
1579 };
1580 mProcessStatsThread.start();
1581 }
1582
1583 @Override
1584 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1585 throws RemoteException {
Dianne Hackborna53de062012-05-08 18:53:51 -07001586 if (code == SYSPROPS_TRANSACTION) {
1587 // We need to tell all apps about the system property change.
1588 ArrayList<IBinder> procs = new ArrayList<IBinder>();
1589 synchronized(this) {
1590 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1591 final int NA = apps.size();
1592 for (int ia=0; ia<NA; ia++) {
1593 ProcessRecord app = apps.valueAt(ia);
1594 if (app.thread != null) {
1595 procs.add(app.thread.asBinder());
1596 }
1597 }
1598 }
1599 }
1600
1601 int N = procs.size();
1602 for (int i=0; i<N; i++) {
1603 Parcel data2 = Parcel.obtain();
1604 try {
1605 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1606 } catch (RemoteException e) {
1607 }
1608 data2.recycle();
1609 }
1610 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 try {
1612 return super.onTransact(code, data, reply, flags);
1613 } catch (RuntimeException e) {
1614 // The activity manager only throws security exceptions, so let's
1615 // log all others.
1616 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001617 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001618 }
1619 throw e;
1620 }
1621 }
1622
1623 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001624 final long now = SystemClock.uptimeMillis();
1625 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1626 return;
1627 }
1628 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1629 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630 mProcessStatsThread.notify();
1631 }
1632 }
1633 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 void updateCpuStatsNow() {
1636 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001637 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001638 final long now = SystemClock.uptimeMillis();
1639 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001641 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001642 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1643 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001644 haveNewCpuStats = true;
1645 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001646 //Slog.i(TAG, mProcessStats.printCurrentState());
1647 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 // + mProcessStats.getTotalCpuPercent() + "%");
1649
Joe Onorato8a9b2202010-02-26 18:56:32 -08001650 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001651 if ("true".equals(SystemProperties.get("events.cpu"))) {
1652 int user = mProcessStats.getLastUserTime();
1653 int system = mProcessStats.getLastSystemTime();
1654 int iowait = mProcessStats.getLastIoWaitTime();
1655 int irq = mProcessStats.getLastIrqTime();
1656 int softIrq = mProcessStats.getLastSoftIrqTime();
1657 int idle = mProcessStats.getLastIdleTime();
1658
1659 int total = user + system + iowait + irq + softIrq + idle;
1660 if (total == 0) total = 1;
1661
Doug Zongker2bec3d42009-12-04 12:52:44 -08001662 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 ((user+system+iowait+irq+softIrq) * 100) / total,
1664 (user * 100) / total,
1665 (system * 100) / total,
1666 (iowait * 100) / total,
1667 (irq * 100) / total,
1668 (softIrq * 100) / total);
1669 }
1670 }
1671
Amith Yamasanie43530a2009-08-21 13:11:37 -07001672 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001673 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001674 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 synchronized(mPidsSelfLocked) {
1676 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001677 if (mOnBattery) {
1678 int perc = bstats.startAddingCpuLocked();
1679 int totalUTime = 0;
1680 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001681 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001682 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001683 ProcessStats.Stats st = mProcessStats.getStats(i);
1684 if (!st.working) {
1685 continue;
1686 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001687 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001688 int otherUTime = (st.rel_utime*perc)/100;
1689 int otherSTime = (st.rel_stime*perc)/100;
1690 totalUTime += otherUTime;
1691 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001692 if (pr != null) {
1693 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001694 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1695 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001696 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001697 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001698 } else {
1699 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001700 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001701 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001702 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1703 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001704 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001705 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 }
1707 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001708 bstats.finishAddingCpuLocked(perc, totalUTime,
1709 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 }
1711 }
1712 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1715 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001716 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001717 }
1718 }
1719 }
1720 }
1721
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001722 @Override
1723 public void batteryNeedsCpuUpdate() {
1724 updateCpuStatsNow();
1725 }
1726
1727 @Override
1728 public void batteryPowerChanged(boolean onBattery) {
1729 // When plugging in, update the CPU stats first before changing
1730 // the plug state.
1731 updateCpuStatsNow();
1732 synchronized (this) {
1733 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001734 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001735 }
1736 }
1737 }
1738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001739 /**
1740 * Initialize the application bind args. These are passed to each
1741 * process when the bindApplication() IPC is sent to the process. They're
1742 * lazily setup to make sure the services are running when they're asked for.
1743 */
1744 private HashMap<String, IBinder> getCommonServicesLocked() {
1745 if (mAppBindArgs == null) {
1746 mAppBindArgs = new HashMap<String, IBinder>();
1747
1748 // Setup the application init args
1749 mAppBindArgs.put("package", ServiceManager.getService("package"));
1750 mAppBindArgs.put("window", ServiceManager.getService("window"));
1751 mAppBindArgs.put(Context.ALARM_SERVICE,
1752 ServiceManager.getService(Context.ALARM_SERVICE));
1753 }
1754 return mAppBindArgs;
1755 }
1756
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001757 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001758 if (mFocusedActivity != r) {
1759 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001760 if (r != null) {
1761 mWindowManager.setFocusedApp(r.appToken, true);
1762 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001763 }
1764 }
1765
Dianne Hackborn906497c2010-05-10 15:57:38 -07001766 private final void updateLruProcessInternalLocked(ProcessRecord app,
1767 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001769 int lrui = mLruProcesses.indexOf(app);
1770 if (lrui >= 0) mLruProcesses.remove(lrui);
1771
1772 int i = mLruProcesses.size()-1;
1773 int skipTop = 0;
1774
Dianne Hackborn906497c2010-05-10 15:57:38 -07001775 app.lruSeq = mLruSeq;
1776
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001777 // compute the new weight for this process.
1778 if (updateActivityTime) {
1779 app.lastActivityTime = SystemClock.uptimeMillis();
1780 }
1781 if (app.activities.size() > 0) {
1782 // If this process has activities, we more strongly want to keep
1783 // it around.
1784 app.lruWeight = app.lastActivityTime;
1785 } else if (app.pubProviders.size() > 0) {
1786 // If this process contains content providers, we want to keep
1787 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001788 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001789 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001790 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001791 } else {
1792 // If this process doesn't have activities, we less strongly
1793 // want to keep it around, and generally want to avoid getting
1794 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001795 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001796 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001797 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001798 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001799
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001800 while (i >= 0) {
1801 ProcessRecord p = mLruProcesses.get(i);
1802 // If this app shouldn't be in front of the first N background
1803 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001804 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001805 skipTop--;
1806 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001807 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001808 mLruProcesses.add(i+1, app);
1809 break;
1810 }
1811 i--;
1812 }
1813 if (i < 0) {
1814 mLruProcesses.add(0, app);
1815 }
1816
Dianne Hackborn906497c2010-05-10 15:57:38 -07001817 // If the app is currently using a content provider or service,
1818 // bump those processes as well.
1819 if (app.connections.size() > 0) {
1820 for (ConnectionRecord cr : app.connections) {
1821 if (cr.binding != null && cr.binding.service != null
1822 && cr.binding.service.app != null
1823 && cr.binding.service.app.lruSeq != mLruSeq) {
Björn Davidsson90f9e312010-11-18 08:26:27 +01001824 updateLruProcessInternalLocked(cr.binding.service.app, false,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001825 updateActivityTime, i+1);
1826 }
1827 }
1828 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001829 for (int j=app.conProviders.size()-1; j>=0; j--) {
1830 ContentProviderRecord cpr = app.conProviders.get(j).provider;
1831 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
Jean-Baptiste Querub8c64052012-06-11 11:01:19 -07001832 updateLruProcessInternalLocked(cpr.proc, false,
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001833 updateActivityTime, i+1);
Dianne Hackborn906497c2010-05-10 15:57:38 -07001834 }
1835 }
1836
Joe Onorato8a9b2202010-02-26 18:56:32 -08001837 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001838 if (oomAdj) {
1839 updateOomAdjLocked();
1840 }
1841 }
1842
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001843 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001844 boolean oomAdj, boolean updateActivityTime) {
1845 mLruSeq++;
1846 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1847 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001848
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001849 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001850 String processName, int uid) {
Amith Yamasania4a54e22012-04-16 15:44:19 -07001851 if (uid == Process.SYSTEM_UID) {
Amith Yamasani0184ce92012-03-28 22:41:41 -07001852 // The system gets to run in any process. If there are multiple
1853 // processes with the same uid, just pick the first (this
1854 // should never happen).
1855 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1856 processName);
Amith Yamasania4a54e22012-04-16 15:44:19 -07001857 if (procs == null) return null;
1858 final int N = procs.size();
1859 for (int i = 0; i < N; i++) {
1860 if (UserId.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
1861 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001862 }
1863 ProcessRecord proc = mProcessNames.get(processName, uid);
1864 return proc;
1865 }
1866
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001867 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001868 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001869 try {
1870 if (pm.performDexOpt(packageName)) {
1871 mDidDexOpt = true;
1872 }
1873 } catch (RemoteException e) {
1874 }
1875 }
1876
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001877 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 int transit = mWindowManager.getPendingAppTransition();
1879 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1880 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1881 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1882 }
1883
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001884 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001886 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1887 boolean isolated) {
1888 ProcessRecord app;
1889 if (!isolated) {
1890 app = getProcessRecordLocked(processName, info.uid);
1891 } else {
1892 // If this is an isolated process, it can't re-use an existing process.
1893 app = null;
1894 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 // We don't have to do anything more if:
1896 // (1) There is an existing application record; and
1897 // (2) The caller doesn't think it is dead, OR there is no thread
1898 // object attached to it so we know it couldn't have crashed; and
1899 // (3) There is a pid assigned to it, so it is either starting or
1900 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001901 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001902 + " app=" + app + " knownToBeDead=" + knownToBeDead
1903 + " thread=" + (app != null ? app.thread : null)
1904 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001905 if (app != null && app.pid > 0) {
1906 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001907 // We already have the app running, or are waiting for it to
1908 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001909 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001910 // If this is a new package in the process, add the package to the list
1911 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001912 return app;
1913 } else {
1914 // An application record is attached to a previous process,
1915 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001916 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001917 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001919 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001921 String hostingNameStr = hostingName != null
1922 ? hostingName.flattenToShortString() : null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001923
1924 if (!isolated) {
1925 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1926 // If we are in the background, then check to see if this process
1927 // is bad. If so, we will just silently fail.
1928 if (mBadProcesses.get(info.processName, info.uid) != null) {
1929 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1930 + "/" + info.processName);
1931 return null;
1932 }
1933 } else {
1934 // When the user is explicitly starting a process, then clear its
1935 // crash count so that we won't make it bad until they see at
1936 // least one crash dialog again, and make the process good again
1937 // if it had been bad.
1938 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001939 + "/" + info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001940 mProcessCrashTimes.remove(info.processName, info.uid);
1941 if (mBadProcesses.get(info.processName, info.uid) != null) {
1942 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1943 info.processName);
1944 mBadProcesses.remove(info.processName, info.uid);
1945 if (app != null) {
1946 app.bad = false;
1947 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001948 }
1949 }
1950 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001953 app = newProcessRecordLocked(null, info, processName, isolated);
1954 if (app == null) {
1955 Slog.w(TAG, "Failed making new process record for "
1956 + processName + "/" + info.uid + " isolated=" + isolated);
1957 return null;
1958 }
1959 mProcessNames.put(processName, app.uid, app);
1960 if (isolated) {
1961 mIsolatedProcesses.put(app.uid, app);
1962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001963 } else {
1964 // If this is a new package in the process, add the package to the list
1965 app.addPackage(info.packageName);
1966 }
1967
1968 // If the system is not ready yet, then hold off on starting this
1969 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001970 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001971 && !isAllowedWhileBooting(info)
1972 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001973 if (!mProcessesOnHold.contains(app)) {
1974 mProcessesOnHold.add(app);
1975 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001976 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001977 return app;
1978 }
1979
1980 startProcessLocked(app, hostingType, hostingNameStr);
1981 return (app.pid != 0) ? app : null;
1982 }
1983
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001984 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1985 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1986 }
1987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988 private final void startProcessLocked(ProcessRecord app,
1989 String hostingType, String hostingNameStr) {
1990 if (app.pid > 0 && app.pid != MY_PID) {
1991 synchronized (mPidsSelfLocked) {
1992 mPidsSelfLocked.remove(app.pid);
1993 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1994 }
1995 app.pid = 0;
1996 }
1997
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001998 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1999 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002000 mProcessesOnHold.remove(app);
2001
2002 updateCpuStats();
2003
2004 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2005 mProcDeaths[0] = 0;
2006
2007 try {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002008 int uid = app.uid;
Amith Yamasani742a6712011-05-04 14:49:28 -07002009
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002010 int[] gids = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002011 if (!app.isolated) {
2012 try {
2013 gids = mContext.getPackageManager().getPackageGids(
2014 app.info.packageName);
2015 } catch (PackageManager.NameNotFoundException e) {
2016 Slog.w(TAG, "Unable to retrieve gids", e);
2017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002018 }
2019 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2020 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2021 && mTopComponent != null
2022 && app.processName.equals(mTopComponent.getPackageName())) {
2023 uid = 0;
2024 }
2025 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2026 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2027 uid = 0;
2028 }
2029 }
2030 int debugFlags = 0;
2031 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2032 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07002033 // Also turn on CheckJNI for debuggable apps. It's quite
2034 // awkward to turn on otherwise.
2035 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08002037 // Run the app in safe mode if its manifest requests so or the
2038 // system is booted in safe mode.
2039 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2040 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08002041 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002043 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2044 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2045 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07002046 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2047 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2048 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002049 if ("1".equals(SystemProperties.get("debug.assert"))) {
2050 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2051 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07002052
2053 // Start the process. It will either succeed and return a result containing
2054 // the PID of the new process, or else throw a RuntimeException.
2055 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Elliott Hughese1dfcb72011-07-08 11:08:07 -07002056 app.processName, uid, uid, gids, debugFlags,
Stephen Smalley83d9eda2012-01-13 08:34:17 -05002057 app.info.targetSdkVersion, null, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002058
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002059 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2060 synchronized (bs) {
2061 if (bs.isOnBattery()) {
2062 app.batteryStats.incStartsLocked();
2063 }
2064 }
2065
Jeff Brown3f9dd282011-07-08 20:02:19 -07002066 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002067 app.processName, hostingType,
2068 hostingNameStr != null ? hostingNameStr : "");
2069
2070 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07002071 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 }
2073
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002074 StringBuilder buf = mStringBuilder;
2075 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076 buf.append("Start proc ");
2077 buf.append(app.processName);
2078 buf.append(" for ");
2079 buf.append(hostingType);
2080 if (hostingNameStr != null) {
2081 buf.append(" ");
2082 buf.append(hostingNameStr);
2083 }
2084 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07002085 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002086 buf.append(" uid=");
2087 buf.append(uid);
2088 buf.append(" gids={");
2089 if (gids != null) {
2090 for (int gi=0; gi<gids.length; gi++) {
2091 if (gi != 0) buf.append(", ");
2092 buf.append(gids[gi]);
2093
2094 }
2095 }
2096 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002097 Slog.i(TAG, buf.toString());
Jeff Brown3f9dd282011-07-08 20:02:19 -07002098 app.pid = startResult.pid;
2099 app.usingWrapper = startResult.usingWrapper;
2100 app.removed = false;
2101 synchronized (mPidsSelfLocked) {
2102 this.mPidsSelfLocked.put(startResult.pid, app);
2103 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2104 msg.obj = app;
2105 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2106 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 }
2108 } catch (RuntimeException e) {
2109 // XXX do better error recovery.
2110 app.pid = 0;
Joe Onorato8a9b2202010-02-26 18:56:32 -08002111 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002112 }
2113 }
2114
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002115 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 if (resumed) {
2117 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2118 } else {
2119 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2120 }
2121 }
2122
Amith Yamasani742a6712011-05-04 14:49:28 -07002123 boolean startHomeActivityLocked(int userId) {
Mike Lockwooda8f767a2011-08-31 14:32:37 -04002124 if (mHeadless) {
2125 // Added because none of the other calls to ensureBootCompleted seem to fire
2126 // when running headless.
2127 ensureBootCompleted();
2128 return false;
2129 }
2130
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002131 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2132 && mTopAction == null) {
2133 // We are running in factory test mode, but unable to find
2134 // the factory test app, so just sit around displaying the
2135 // error message and don't try to start anything.
2136 return false;
2137 }
2138 Intent intent = new Intent(
2139 mTopAction,
2140 mTopData != null ? Uri.parse(mTopData) : null);
2141 intent.setComponent(mTopComponent);
2142 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2143 intent.addCategory(Intent.CATEGORY_HOME);
2144 }
2145 ActivityInfo aInfo =
2146 intent.resolveActivityInfo(mContext.getPackageManager(),
2147 STOCK_PM_FLAGS);
2148 if (aInfo != null) {
2149 intent.setComponent(new ComponentName(
2150 aInfo.applicationInfo.packageName, aInfo.name));
2151 // Don't do this if the home app is currently being
2152 // instrumented.
Amith Yamasani742a6712011-05-04 14:49:28 -07002153 aInfo = new ActivityInfo(aInfo);
2154 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002155 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2156 aInfo.applicationInfo.uid);
2157 if (app == null || app.instrumentationClass == null) {
2158 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborna4972e92012-03-14 10:38:05 -07002159 mMainStack.startActivityLocked(null, intent, null, aInfo,
2160 null, null, 0, 0, 0, 0, null, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002161 }
2162 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002163
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002164 return true;
2165 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002166
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002167 /**
2168 * Starts the "new version setup screen" if appropriate.
2169 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002170 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002171 // Only do this once per boot.
2172 if (mCheckedForSetup) {
2173 return;
2174 }
2175
2176 // We will show this screen if the current one is a different
2177 // version than the last one shown, and we are not running in
2178 // low-level factory test mode.
2179 final ContentResolver resolver = mContext.getContentResolver();
2180 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2181 Settings.Secure.getInt(resolver,
2182 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2183 mCheckedForSetup = true;
2184
2185 // See if we should be showing the platform update setup UI.
2186 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2187 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2188 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2189
2190 // We don't allow third party apps to replace this.
2191 ResolveInfo ri = null;
2192 for (int i=0; ris != null && i<ris.size(); i++) {
2193 if ((ris.get(i).activityInfo.applicationInfo.flags
2194 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2195 ri = ris.get(i);
2196 break;
2197 }
2198 }
2199
2200 if (ri != null) {
2201 String vers = ri.activityInfo.metaData != null
2202 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2203 : null;
2204 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2205 vers = ri.activityInfo.applicationInfo.metaData.getString(
2206 Intent.METADATA_SETUP_VERSION);
2207 }
2208 String lastVers = Settings.Secure.getString(
2209 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2210 if (vers != null && !vers.equals(lastVers)) {
2211 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2212 intent.setComponent(new ComponentName(
2213 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborna4972e92012-03-14 10:38:05 -07002214 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2215 null, null, 0, 0, 0, 0, null, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002216 }
2217 }
2218 }
2219 }
2220
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002221 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002222 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002223 }
2224
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002225 void enforceNotIsolatedCaller(String caller) {
2226 if (UserId.isIsolated(Binder.getCallingUid())) {
2227 throw new SecurityException("Isolated process not allowed to call " + caller);
2228 }
2229 }
2230
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002231 public int getFrontActivityScreenCompatMode() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002232 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002233 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002234 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2235 }
2236 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002237
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002238 public void setFrontActivityScreenCompatMode(int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002239 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2240 "setFrontActivityScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002241 synchronized (this) {
2242 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2243 }
2244 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002245
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002246 public int getPackageScreenCompatMode(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002247 enforceNotIsolatedCaller("getPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002248 synchronized (this) {
2249 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2250 }
2251 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002252
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002253 public void setPackageScreenCompatMode(String packageName, int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002254 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2255 "setPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002256 synchronized (this) {
2257 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002258 }
2259 }
2260
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002261 public boolean getPackageAskScreenCompat(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002262 enforceNotIsolatedCaller("getPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002263 synchronized (this) {
2264 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2265 }
2266 }
2267
2268 public void setPackageAskScreenCompat(String packageName, boolean ask) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002269 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2270 "setPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002271 synchronized (this) {
2272 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2273 }
2274 }
2275
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002276 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002277 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002278 updateUsageStats(r, true);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280
Dianne Hackborna93c2c12012-05-31 15:29:36 -07002281 private void dispatchProcessesChanged() {
2282 int N;
2283 synchronized (this) {
2284 N = mPendingProcessChanges.size();
2285 if (mActiveProcessChanges.length < N) {
2286 mActiveProcessChanges = new ProcessChangeItem[N];
2287 }
2288 mPendingProcessChanges.toArray(mActiveProcessChanges);
2289 mAvailProcessChanges.addAll(mPendingProcessChanges);
2290 mPendingProcessChanges.clear();
2291 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2292 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07002293 int i = mProcessObservers.beginBroadcast();
2294 while (i > 0) {
2295 i--;
2296 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2297 if (observer != null) {
2298 try {
Dianne Hackborna93c2c12012-05-31 15:29:36 -07002299 for (int j=0; j<N; j++) {
2300 ProcessChangeItem item = mActiveProcessChanges[j];
2301 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2302 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2303 + item.pid + " uid=" + item.uid + ": "
2304 + item.foregroundActivities);
2305 observer.onForegroundActivitiesChanged(item.pid, item.uid,
2306 item.foregroundActivities);
2307 }
2308 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2309 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2310 + item.pid + " uid=" + item.uid + ": " + item.importance);
2311 observer.onImportanceChanged(item.pid, item.uid,
2312 item.importance);
2313 }
2314 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07002315 } catch (RemoteException e) {
2316 }
2317 }
2318 }
2319 mProcessObservers.finishBroadcast();
2320 }
2321
2322 private void dispatchProcessDied(int pid, int uid) {
2323 int i = mProcessObservers.beginBroadcast();
2324 while (i > 0) {
2325 i--;
2326 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2327 if (observer != null) {
2328 try {
2329 observer.onProcessDied(pid, uid);
2330 } catch (RemoteException e) {
2331 }
2332 }
2333 }
2334 mProcessObservers.finishBroadcast();
2335 }
2336
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002337 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002338 final int N = mPendingActivityLaunches.size();
2339 if (N <= 0) {
2340 return;
2341 }
2342 for (int i=0; i<N; i++) {
2343 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002344 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002345 pal.startFlags, doResume && i == (N-1), null);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002346 }
2347 mPendingActivityLaunches.clear();
2348 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002349
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002350 public final int startActivity(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002351 Intent intent, String resolvedType, IBinder resultTo,
2352 String resultWho, int requestCode, int startFlags,
2353 String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002354 enforceNotIsolatedCaller("startActivity");
Amith Yamasani742a6712011-05-04 14:49:28 -07002355 int userId = 0;
2356 if (intent.getCategories() != null && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2357 // Requesting home, set the identity to the current user
2358 // HACK!
2359 userId = mCurrentUserId;
2360 } else {
2361 // TODO: Fix this in a better way - calls coming from SystemUI should probably carry
2362 // the current user's userId
2363 if (Binder.getCallingUid() < Process.FIRST_APPLICATION_UID) {
2364 userId = 0;
2365 } else {
2366 userId = Binder.getOrigCallingUser();
2367 }
2368 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002369 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002370 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2371 null, null, options, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002372 }
2373
2374 public final WaitResult startActivityAndWait(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002375 Intent intent, String resolvedType, IBinder resultTo,
2376 String resultWho, int requestCode, int startFlags, String profileFile,
2377 ParcelFileDescriptor profileFd, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002378 enforceNotIsolatedCaller("startActivityAndWait");
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002379 WaitResult res = new WaitResult();
Amith Yamasani742a6712011-05-04 14:49:28 -07002380 int userId = Binder.getOrigCallingUser();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002381 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002382 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2383 res, null, options, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002384 return res;
2385 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08002386
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002387 public final int startActivityWithConfig(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002388 Intent intent, String resolvedType, IBinder resultTo,
2389 String resultWho, int requestCode, int startFlags, Configuration config,
2390 Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002391 enforceNotIsolatedCaller("startActivityWithConfig");
Amith Yamasani742a6712011-05-04 14:49:28 -07002392 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002393 resultTo, resultWho, requestCode, startFlags,
2394 null, null, null, config, options, Binder.getOrigCallingUser());
Amith Yamasani742a6712011-05-04 14:49:28 -07002395 return ret;
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002396 }
2397
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002398 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002399 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002400 IBinder resultTo, String resultWho, int requestCode,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002401 int flagsMask, int flagsValues, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002402 enforceNotIsolatedCaller("startActivityIntentSender");
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002403 // Refuse possible leaked file descriptors
2404 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2405 throw new IllegalArgumentException("File descriptors passed in Intent");
2406 }
2407
2408 IIntentSender sender = intent.getTarget();
2409 if (!(sender instanceof PendingIntentRecord)) {
2410 throw new IllegalArgumentException("Bad PendingIntent object");
2411 }
2412
2413 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002414
2415 synchronized (this) {
2416 // If this is coming from the currently resumed activity, it is
2417 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002418 if (mMainStack.mResumedActivity != null
2419 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002420 Binder.getCallingUid()) {
2421 mAppSwitchesAllowedTime = 0;
2422 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002423 }
Dianne Hackborna4972e92012-03-14 10:38:05 -07002424 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2425 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
Amith Yamasani742a6712011-05-04 14:49:28 -07002426 return ret;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002427 }
2428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 public boolean startNextMatchingActivity(IBinder callingActivity,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002430 Intent intent, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431 // Refuse possible leaked file descriptors
2432 if (intent != null && intent.hasFileDescriptors() == true) {
2433 throw new IllegalArgumentException("File descriptors passed in Intent");
2434 }
2435
2436 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002437 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2438 if (r == null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002439 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 return false;
2441 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 if (r.app == null || r.app.thread == null) {
2443 // The caller is not running... d'oh!
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002444 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002445 return false;
2446 }
2447 intent = new Intent(intent);
2448 // The caller is not allowed to change the data.
2449 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2450 // And we are resetting to find the next component...
2451 intent.setComponent(null);
2452
2453 ActivityInfo aInfo = null;
2454 try {
2455 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002456 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 intent, r.resolvedType,
Amith Yamasani483f3b02012-03-13 16:08:00 -07002458 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
2459 UserId.getCallingUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002460
2461 // Look for the original activity in the list...
2462 final int N = resolves != null ? resolves.size() : 0;
2463 for (int i=0; i<N; i++) {
2464 ResolveInfo rInfo = resolves.get(i);
2465 if (rInfo.activityInfo.packageName.equals(r.packageName)
2466 && rInfo.activityInfo.name.equals(r.info.name)) {
2467 // We found the current one... the next matching is
2468 // after it.
2469 i++;
2470 if (i<N) {
2471 aInfo = resolves.get(i).activityInfo;
2472 }
2473 break;
2474 }
2475 }
2476 } catch (RemoteException e) {
2477 }
2478
2479 if (aInfo == null) {
2480 // Nobody who is next!
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002481 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002482 return false;
2483 }
2484
2485 intent.setComponent(new ComponentName(
2486 aInfo.applicationInfo.packageName, aInfo.name));
2487 intent.setFlags(intent.getFlags()&~(
2488 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2489 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2490 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2491 Intent.FLAG_ACTIVITY_NEW_TASK));
2492
2493 // Okay now we need to start the new activity, replacing the
2494 // currently running activity. This is a little tricky because
2495 // we want to start the new one as if the current one is finished,
2496 // but not finish the current one first so that there is no flicker.
2497 // And thus...
2498 final boolean wasFinishing = r.finishing;
2499 r.finishing = true;
2500
2501 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002502 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002503 final String resultWho = r.resultWho;
2504 final int requestCode = r.requestCode;
2505 r.resultTo = null;
2506 if (resultTo != null) {
2507 resultTo.removeResultsLocked(r, resultWho, requestCode);
2508 }
2509
2510 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002511 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002512 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2513 resultWho, requestCode, -1, r.launchedFromUid, 0,
2514 options, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 Binder.restoreCallingIdentity(origId);
2516
2517 r.finishing = wasFinishing;
Dianne Hackborna4972e92012-03-14 10:38:05 -07002518 if (res != ActivityManager.START_SUCCESS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 return false;
2520 }
2521 return true;
2522 }
2523 }
2524
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002525 public final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 Intent intent, String resolvedType, IBinder resultTo,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002527 String resultWho, int requestCode, int startFlags, Bundle options) {
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002528
2529 // This is so super not safe, that only the system (or okay root)
2530 // can do it.
Amith Yamasani742a6712011-05-04 14:49:28 -07002531 int userId = Binder.getOrigCallingUser();
Dianne Hackborn2d91af02009-07-16 13:34:33 -07002532 final int callingUid = Binder.getCallingUid();
2533 if (callingUid != 0 && callingUid != Process.myUid()) {
2534 throw new SecurityException(
2535 "startActivityInPackage only available to the system");
2536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002537
Amith Yamasani742a6712011-05-04 14:49:28 -07002538 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002539 resultTo, resultWho, requestCode, startFlags,
2540 null, null, null, null, options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002541 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002542 }
2543
2544 public final int startActivities(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002545 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002546 enforceNotIsolatedCaller("startActivities");
Amith Yamasani742a6712011-05-04 14:49:28 -07002547 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002548 options, Binder.getOrigCallingUser());
Amith Yamasani742a6712011-05-04 14:49:28 -07002549 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002550 }
2551
2552 public final int startActivitiesInPackage(int uid,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002553 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
2554 Bundle options) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002555
2556 // This is so super not safe, that only the system (or okay root)
2557 // can do it.
2558 final int callingUid = Binder.getCallingUid();
2559 if (callingUid != 0 && callingUid != Process.myUid()) {
2560 throw new SecurityException(
2561 "startActivityInPackage only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002562 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002563 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002564 options, UserId.getUserId(uid));
Amith Yamasani742a6712011-05-04 14:49:28 -07002565 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002566 }
2567
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002568 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002570 // Quick case: check if the top-most recent task is the same.
2571 if (N > 0 && mRecentTasks.get(0) == task) {
2572 return;
2573 }
2574 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002575 for (int i=0; i<N; i++) {
2576 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07002577 if (task.userId == tr.userId
2578 && ((task.affinity != null && task.affinity.equals(tr.affinity))
2579 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002580 mRecentTasks.remove(i);
2581 i--;
2582 N--;
2583 if (task.intent == null) {
2584 // If the new recent task we are adding is not fully
2585 // specified, then replace it with the existing recent task.
2586 task = tr;
2587 }
2588 }
2589 }
2590 if (N >= MAX_RECENT_TASKS) {
2591 mRecentTasks.remove(N-1);
2592 }
2593 mRecentTasks.add(0, task);
2594 }
2595
2596 public void setRequestedOrientation(IBinder token,
2597 int requestedOrientation) {
2598 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002599 ActivityRecord r = mMainStack.isInStackLocked(token);
2600 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 return;
2602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002604 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002606 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002607 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 if (config != null) {
2609 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002610 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002611 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 }
2613 }
2614 Binder.restoreCallingIdentity(origId);
2615 }
2616 }
2617
2618 public int getRequestedOrientation(IBinder token) {
2619 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002620 ActivityRecord r = mMainStack.isInStackLocked(token);
2621 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2623 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002624 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 }
2626 }
2627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 /**
2629 * This is the internal entry point for handling Activity.finish().
2630 *
2631 * @param token The Binder token referencing the Activity we want to finish.
2632 * @param resultCode Result code, if any, from this Activity.
2633 * @param resultData Result data (Intent), if any, from this Activity.
2634 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002635 * @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 -08002636 */
2637 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2638 // Refuse possible leaked file descriptors
2639 if (resultData != null && resultData.hasFileDescriptors() == true) {
2640 throw new IllegalArgumentException("File descriptors passed in Intent");
2641 }
2642
2643 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002644 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002646 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 if (next != null) {
2648 // ask watcher if this is allowed
2649 boolean resumeOK = true;
2650 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002651 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002653 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 }
2655
2656 if (!resumeOK) {
2657 return false;
2658 }
2659 }
2660 }
2661 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002662 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 resultData, "app-request");
2664 Binder.restoreCallingIdentity(origId);
2665 return res;
2666 }
2667 }
2668
Dianne Hackborn860755f2010-06-03 18:47:52 -07002669 public final void finishHeavyWeightApp() {
2670 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2671 != PackageManager.PERMISSION_GRANTED) {
2672 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2673 + Binder.getCallingPid()
2674 + ", uid=" + Binder.getCallingUid()
2675 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2676 Slog.w(TAG, msg);
2677 throw new SecurityException(msg);
2678 }
2679
2680 synchronized(this) {
2681 if (mHeavyWeightProcess == null) {
2682 return;
2683 }
2684
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002685 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002686 mHeavyWeightProcess.activities);
2687 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002688 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002689 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002690 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002691 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002692 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002693 null, "finish-heavy");
2694 }
2695 }
2696 }
2697
2698 mHeavyWeightProcess = null;
2699 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
2700 }
2701 }
2702
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002703 public void crashApplication(int uid, int initialPid, String packageName,
2704 String message) {
2705 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2706 != PackageManager.PERMISSION_GRANTED) {
2707 String msg = "Permission Denial: crashApplication() from pid="
2708 + Binder.getCallingPid()
2709 + ", uid=" + Binder.getCallingUid()
2710 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2711 Slog.w(TAG, msg);
2712 throw new SecurityException(msg);
2713 }
2714
2715 synchronized(this) {
2716 ProcessRecord proc = null;
2717
2718 // Figure out which process to kill. We don't trust that initialPid
2719 // still has any relation to current pids, so must scan through the
2720 // list.
2721 synchronized (mPidsSelfLocked) {
2722 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2723 ProcessRecord p = mPidsSelfLocked.valueAt(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002724 if (p.uid != uid) {
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002725 continue;
2726 }
2727 if (p.pid == initialPid) {
2728 proc = p;
2729 break;
2730 }
2731 for (String str : p.pkgList) {
2732 if (str.equals(packageName)) {
2733 proc = p;
2734 }
2735 }
2736 }
2737 }
2738
2739 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002740 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002741 + " initialPid=" + initialPid
2742 + " packageName=" + packageName);
2743 return;
2744 }
2745
2746 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002747 if (proc.pid == Process.myPid()) {
2748 Log.w(TAG, "crashApplication: trying to crash self!");
2749 return;
2750 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002751 long ident = Binder.clearCallingIdentity();
2752 try {
2753 proc.thread.scheduleCrash(message);
2754 } catch (RemoteException e) {
2755 }
2756 Binder.restoreCallingIdentity(ident);
2757 }
2758 }
2759 }
2760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002761 public final void finishSubActivity(IBinder token, String resultWho,
2762 int requestCode) {
2763 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002765 mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002766 Binder.restoreCallingIdentity(origId);
2767 }
2768 }
2769
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002770 public boolean finishActivityAffinity(IBinder token) {
2771 synchronized(this) {
2772 final long origId = Binder.clearCallingIdentity();
2773 boolean res = mMainStack.finishActivityAffinityLocked(token);
2774 Binder.restoreCallingIdentity(origId);
2775 return res;
2776 }
2777 }
2778
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002779 public boolean willActivityBeVisible(IBinder token) {
2780 synchronized(this) {
2781 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002782 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2783 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002784 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002785 return true;
2786 }
2787 if (r.fullscreen && !r.finishing) {
2788 return false;
2789 }
2790 }
2791 return true;
2792 }
2793 }
2794
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002795 public void overridePendingTransition(IBinder token, String packageName,
2796 int enterAnim, int exitAnim) {
2797 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002798 ActivityRecord self = mMainStack.isInStackLocked(token);
2799 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002800 return;
2801 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002802
2803 final long origId = Binder.clearCallingIdentity();
2804
2805 if (self.state == ActivityState.RESUMED
2806 || self.state == ActivityState.PAUSING) {
2807 mWindowManager.overridePendingAppTransition(packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07002808 enterAnim, exitAnim, null);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002809 }
2810
2811 Binder.restoreCallingIdentity(origId);
2812 }
2813 }
2814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002815 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 * Main function for removing an existing process from the activity manager
2817 * as a result of that process going away. Clears out all connections
2818 * to the process.
2819 */
2820 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002821 boolean restarting, boolean allowRestart) {
2822 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002824 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 }
2826
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002827 if (mProfileProc == app) {
2828 clearProfilerLocked();
2829 }
2830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831 // Just in case...
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002832 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2833 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2834 mMainStack.mPausingActivity = null;
2835 }
2836 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2837 mMainStack.mLastPausedActivity = null;
2838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839
2840 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002841 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002842
2843 boolean atTop = true;
2844 boolean hasVisibleActivities = false;
2845
2846 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002847 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002848 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002849 TAG, "Removing app " + app + " from history with " + i + " entries");
2850 while (i > 0) {
2851 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002852 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002853 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002854 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2855 if (r.app == app) {
2856 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002857 if (ActivityStack.DEBUG_ADD_REMOVE) {
2858 RuntimeException here = new RuntimeException("here");
2859 here.fillInStackTrace();
2860 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2861 + ": haveState=" + r.haveState
2862 + " stateNotNeeded=" + r.stateNotNeeded
2863 + " finishing=" + r.finishing
2864 + " state=" + r.state, here);
2865 }
2866 if (!r.finishing) {
2867 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08002868 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2869 System.identityHashCode(r),
2870 r.task.taskId, r.shortComponentName,
2871 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002872 }
Dianne Hackborn5c607432012-02-28 14:44:19 -08002873 mMainStack.removeActivityFromHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002874
2875 } else {
2876 // We have the current state for this activity, so
2877 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002878 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002879 TAG, "Keeping entry, setting app to null");
2880 if (r.visible) {
2881 hasVisibleActivities = true;
2882 }
2883 r.app = null;
2884 r.nowVisible = false;
2885 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002886 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2887 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002888 r.icicle = null;
2889 }
2890 }
2891
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002892 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 }
2894 atTop = false;
2895 }
2896
2897 app.activities.clear();
2898
2899 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002900 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002901 + " running instrumentation " + app.instrumentationClass);
2902 Bundle info = new Bundle();
2903 info.putString("shortMsg", "Process crashed.");
2904 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2905 }
2906
2907 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002908 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002909 // If there was nothing to resume, and we are not already
2910 // restarting this process, but there is a visible activity that
2911 // is hosted by the process... then make sure all visible
2912 // activities are running, taking care of restarting this
2913 // process.
2914 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002915 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916 }
2917 }
2918 }
2919 }
2920
2921 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2922 IBinder threadBinder = thread.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002923 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002924 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2925 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2927 return i;
2928 }
2929 }
2930 return -1;
2931 }
2932
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002933 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002934 IApplicationThread thread) {
2935 if (thread == null) {
2936 return null;
2937 }
2938
2939 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002940 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 }
2942
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002943 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002944 IApplicationThread thread) {
2945
2946 mProcDeaths[0]++;
2947
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002948 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2949 synchronized (stats) {
2950 stats.noteProcessDiedLocked(app.info.uid, pid);
2951 }
2952
Magnus Edlund7bb25812010-02-24 15:45:06 +01002953 // Clean up already done if the process has been re-started.
2954 if (app.pid == pid && app.thread != null &&
2955 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002956 if (!app.killedBackground) {
2957 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2958 + ") has died.");
2959 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002960 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002961 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002962 TAG, "Dying app: " + app + ", pid: " + pid
2963 + ", thread: " + thread.asBinder());
2964 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002965 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002966
2967 if (doLowMem) {
2968 // If there are no longer any background processes running,
2969 // and the app that died was not running instrumentation,
2970 // then tell everyone we are now low on memory.
2971 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002972 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2973 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002974 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 haveBg = true;
2976 break;
2977 }
2978 }
2979
2980 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002981 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002982 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002983 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2984 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002985 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002986 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2987 // The low memory report is overriding any current
2988 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002989 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002990 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002991 rec.lastRequestedGc = 0;
2992 } else {
2993 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002994 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002995 rec.reportLowMemory = true;
2996 rec.lastLowMemory = now;
2997 mProcessesToGc.remove(rec);
2998 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002999 }
3000 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07003001 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003002 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003003 }
3004 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01003005 } else if (app.pid != pid) {
3006 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003007 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01003008 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08003009 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003010 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003011 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003012 + thread.asBinder());
3013 }
3014 }
3015
Dan Egnor42471dd2010-01-07 17:25:22 -08003016 /**
3017 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07003018 * @param clearTraces causes the dump file to be erased prior to the new
3019 * traces being written, if true; when false, the new traces will be
3020 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003021 * @param firstPids of dalvik VM processes to dump stack traces for first
3022 * @param lastPids of dalvik VM processes to dump stack traces for last
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003023 * @param nativeProcs optional list of native process names to dump stack crawls
Dan Egnor42471dd2010-01-07 17:25:22 -08003024 * @return file containing stack traces, or null if no dump file is configured
3025 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003026 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003027 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003028 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3029 if (tracesPath == null || tracesPath.length() == 0) {
3030 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003031 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003032
3033 File tracesFile = new File(tracesPath);
3034 try {
3035 File tracesDir = tracesFile.getParentFile();
rpcraigec7ed14c2012-07-25 13:10:37 -04003036 if (!tracesDir.exists()) {
3037 tracesFile.mkdirs();
3038 if (!SELinux.restorecon(tracesDir)) {
3039 return null;
3040 }
3041 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003042 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3043
Christopher Tate6ee412d2010-05-28 12:01:56 -07003044 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08003045 tracesFile.createNewFile();
3046 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3047 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003048 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08003049 return null;
3050 }
3051
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003052 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003053 return tracesFile;
3054 }
3055
3056 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003057 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003058 // Use a FileObserver to detect when traces finish writing.
3059 // The order of traces is considered important to maintain for legibility.
3060 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3061 public synchronized void onEvent(int event, String path) { notify(); }
3062 };
3063
3064 try {
3065 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003066
3067 // First collect all of the stacks of the most important pids.
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003068 if (firstPids != null) {
3069 try {
3070 int num = firstPids.size();
3071 for (int i = 0; i < num; i++) {
3072 synchronized (observer) {
3073 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3074 observer.wait(200); // Wait for write-close, give up after 200msec
3075 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003076 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003077 } catch (InterruptedException e) {
3078 Log.wtf(TAG, e);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003079 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003080 }
3081
3082 // Next measure CPU usage.
3083 if (processStats != null) {
3084 processStats.init();
3085 System.gc();
3086 processStats.update();
3087 try {
3088 synchronized (processStats) {
3089 processStats.wait(500); // measure over 1/2 second.
3090 }
3091 } catch (InterruptedException e) {
3092 }
3093 processStats.update();
3094
3095 // We'll take the stack crawls of just the top apps using CPU.
3096 final int N = processStats.countWorkingStats();
3097 int numProcs = 0;
3098 for (int i=0; i<N && numProcs<5; i++) {
3099 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3100 if (lastPids.indexOfKey(stats.pid) >= 0) {
3101 numProcs++;
3102 try {
3103 synchronized (observer) {
3104 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3105 observer.wait(200); // Wait for write-close, give up after 200msec
3106 }
3107 } catch (InterruptedException e) {
3108 Log.wtf(TAG, e);
3109 }
3110
3111 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003112 }
3113 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003114
Dan Egnor42471dd2010-01-07 17:25:22 -08003115 } finally {
3116 observer.stopWatching();
3117 }
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003118
3119 if (nativeProcs != null) {
3120 int[] pids = Process.getPidsForCommands(nativeProcs);
3121 if (pids != null) {
3122 for (int pid : pids) {
3123 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3124 }
3125 }
3126 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 }
3128
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003129 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
Dianne Hackborn69dc66e2012-03-26 10:50:54 -07003130 if (true || IS_USER_BUILD) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003131 return;
3132 }
3133 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3134 if (tracesPath == null || tracesPath.length() == 0) {
3135 return;
3136 }
3137
3138 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3139 StrictMode.allowThreadDiskWrites();
3140 try {
3141 final File tracesFile = new File(tracesPath);
3142 final File tracesDir = tracesFile.getParentFile();
3143 final File tracesTmp = new File(tracesDir, "__tmp__");
3144 try {
rpcraigec7ed14c2012-07-25 13:10:37 -04003145 if (!tracesDir.exists()) {
3146 tracesFile.mkdirs();
3147 if (!SELinux.restorecon(tracesDir.getPath())) {
3148 return;
3149 }
3150 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003151 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3152
3153 if (tracesFile.exists()) {
3154 tracesTmp.delete();
3155 tracesFile.renameTo(tracesTmp);
3156 }
3157 StringBuilder sb = new StringBuilder();
3158 Time tobj = new Time();
3159 tobj.set(System.currentTimeMillis());
3160 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3161 sb.append(": ");
3162 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3163 sb.append(" since ");
3164 sb.append(msg);
3165 FileOutputStream fos = new FileOutputStream(tracesFile);
3166 fos.write(sb.toString().getBytes());
3167 if (app == null) {
3168 fos.write("\n*** No application process!".getBytes());
3169 }
3170 fos.close();
3171 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3172 } catch (IOException e) {
3173 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3174 return;
3175 }
3176
3177 if (app != null) {
3178 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3179 firstPids.add(app.pid);
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003180 dumpStackTraces(tracesPath, firstPids, null, null, null);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003181 }
3182
3183 File lastTracesFile = null;
3184 File curTracesFile = null;
3185 for (int i=9; i>=0; i--) {
3186 String name = String.format("slow%02d.txt", i);
3187 curTracesFile = new File(tracesDir, name);
3188 if (curTracesFile.exists()) {
3189 if (lastTracesFile != null) {
3190 curTracesFile.renameTo(lastTracesFile);
3191 } else {
3192 curTracesFile.delete();
3193 }
3194 }
3195 lastTracesFile = curTracesFile;
3196 }
3197 tracesFile.renameTo(curTracesFile);
3198 if (tracesTmp.exists()) {
3199 tracesTmp.renameTo(tracesFile);
3200 }
3201 } finally {
3202 StrictMode.setThreadPolicy(oldPolicy);
3203 }
3204 }
3205
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003206 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3207 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003208 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3209 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3210
Dianne Hackborn287952c2010-09-22 22:34:31 -07003211 if (mController != null) {
3212 try {
3213 // 0 == continue, -1 = kill process immediately
3214 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3215 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3216 } catch (RemoteException e) {
3217 mController = null;
3218 }
3219 }
3220
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003221 long anrTime = SystemClock.uptimeMillis();
3222 if (MONITOR_CPU_USAGE) {
3223 updateCpuStatsNow();
3224 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003225
3226 synchronized (this) {
3227 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3228 if (mShuttingDown) {
3229 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3230 return;
3231 } else if (app.notResponding) {
3232 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3233 return;
3234 } else if (app.crashing) {
3235 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3236 return;
3237 }
3238
3239 // In case we come through here for the same app before completing
3240 // this one, mark as anring now so we will bail out.
3241 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003242
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003243 // Log the ANR to the event log.
3244 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3245 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003246
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003247 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003248 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003249
3250 int parentPid = app.pid;
3251 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003252 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003253
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003254 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003255
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003256 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3257 ProcessRecord r = mLruProcesses.get(i);
3258 if (r != null && r.thread != null) {
3259 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003260 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3261 if (r.persistent) {
3262 firstPids.add(pid);
3263 } else {
3264 lastPids.put(pid, Boolean.TRUE);
3265 }
3266 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003267 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 }
3269 }
3270
Dan Egnor42471dd2010-01-07 17:25:22 -08003271 // Log the ANR to the main log.
Jeff Browndeb6ed82012-04-10 14:26:26 -07003272 StringBuilder info = new StringBuilder();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003273 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003274 info.append("ANR in ").append(app.processName);
3275 if (activity != null && activity.shortComponentName != null) {
3276 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003277 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003278 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003280 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003281 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003282 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003283 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285
Dianne Hackborn287952c2010-09-22 22:34:31 -07003286 final ProcessStats processStats = new ProcessStats(true);
3287
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003288 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003289
Dan Egnor42471dd2010-01-07 17:25:22 -08003290 String cpuInfo = null;
3291 if (MONITOR_CPU_USAGE) {
3292 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003293 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003294 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003295 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003296 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003297 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003298 }
3299
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003300 info.append(processStats.printCurrentState(anrTime));
3301
Joe Onorato8a9b2202010-02-26 18:56:32 -08003302 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003303 if (tracesFile == null) {
3304 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3305 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3306 }
3307
Jeff Sharkeya353d262011-10-28 11:12:06 -07003308 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3309 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003310
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003311 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003312 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003313 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3314 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003316 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3317 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 }
3319 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003320 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003321 }
3322 }
3323
Dan Egnor42471dd2010-01-07 17:25:22 -08003324 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3325 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3326 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003327
3328 synchronized (this) {
3329 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003330 Slog.w(TAG, "Killing " + app + ": background ANR");
3331 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3332 app.processName, app.setAdj, "background ANR");
3333 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003334 return;
3335 }
3336
3337 // Set the app's notResponding state, and look up the errorReportReceiver
3338 makeAppNotRespondingLocked(app,
3339 activity != null ? activity.shortComponentName : null,
3340 annotation != null ? "ANR " + annotation : "ANR",
3341 info.toString());
3342
3343 // Bring up the infamous App Not Responding dialog
3344 Message msg = Message.obtain();
3345 HashMap map = new HashMap();
3346 msg.what = SHOW_NOT_RESPONDING_MSG;
3347 msg.obj = map;
3348 map.put("app", app);
3349 if (activity != null) {
3350 map.put("activity", activity);
3351 }
3352
3353 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003354 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003355 }
3356
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003357 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3358 if (!mLaunchWarningShown) {
3359 mLaunchWarningShown = true;
3360 mHandler.post(new Runnable() {
3361 @Override
3362 public void run() {
3363 synchronized (ActivityManagerService.this) {
3364 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3365 d.show();
3366 mHandler.postDelayed(new Runnable() {
3367 @Override
3368 public void run() {
3369 synchronized (ActivityManagerService.this) {
3370 d.dismiss();
3371 mLaunchWarningShown = false;
3372 }
3373 }
3374 }, 4000);
3375 }
3376 }
3377 });
3378 }
3379 }
3380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 public boolean clearApplicationUserData(final String packageName,
Amith Yamasani742a6712011-05-04 14:49:28 -07003382 final IPackageDataObserver observer, final int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003383 enforceNotIsolatedCaller("clearApplicationUserData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 int uid = Binder.getCallingUid();
3385 int pid = Binder.getCallingPid();
3386 long callingId = Binder.clearCallingIdentity();
3387 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003388 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003389 int pkgUid = -1;
3390 synchronized(this) {
3391 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003392 pkgUid = pm.getPackageUid(packageName, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 } catch (RemoteException e) {
3394 }
3395 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003396 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003397 return false;
3398 }
3399 if (uid == pkgUid || checkComponentPermission(
3400 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003401 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003403 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003404 } else {
3405 throw new SecurityException(pid+" does not have permission:"+
3406 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3407 "for process:"+packageName);
3408 }
3409 }
3410
3411 try {
3412 //clear application user data
Amith Yamasani483f3b02012-03-13 16:08:00 -07003413 pm.clearApplicationUserData(packageName, observer, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003414 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3415 Uri.fromParts("package", packageName, null));
3416 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003417 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
Amith Yamasani742a6712011-05-04 14:49:28 -07003418 null, null, 0, null, null, null, false, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 } catch (RemoteException e) {
3420 }
3421 } finally {
3422 Binder.restoreCallingIdentity(callingId);
3423 }
3424 return true;
3425 }
3426
Dianne Hackborn03abb812010-01-04 18:43:19 -08003427 public void killBackgroundProcesses(final String packageName) {
3428 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3429 != PackageManager.PERMISSION_GRANTED &&
3430 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3431 != PackageManager.PERMISSION_GRANTED) {
3432 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003433 + Binder.getCallingPid()
3434 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003435 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003436 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 throw new SecurityException(msg);
3438 }
3439
Amith Yamasani483f3b02012-03-13 16:08:00 -07003440 int userId = UserId.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 long callingId = Binder.clearCallingIdentity();
3442 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003443 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003444 int pkgUid = -1;
3445 synchronized(this) {
3446 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003447 pkgUid = pm.getPackageUid(packageName, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003448 } catch (RemoteException e) {
3449 }
3450 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003451 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003452 return;
3453 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003454 killPackageProcessesLocked(packageName, pkgUid,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003455 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3456 }
3457 } finally {
3458 Binder.restoreCallingIdentity(callingId);
3459 }
3460 }
3461
3462 public void killAllBackgroundProcesses() {
3463 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3464 != PackageManager.PERMISSION_GRANTED) {
3465 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3466 + Binder.getCallingPid()
3467 + ", uid=" + Binder.getCallingUid()
3468 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3469 Slog.w(TAG, msg);
3470 throw new SecurityException(msg);
3471 }
3472
3473 long callingId = Binder.clearCallingIdentity();
3474 try {
3475 synchronized(this) {
3476 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3477 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3478 final int NA = apps.size();
3479 for (int ia=0; ia<NA; ia++) {
3480 ProcessRecord app = apps.valueAt(ia);
3481 if (app.persistent) {
3482 // we don't kill persistent processes
3483 continue;
3484 }
3485 if (app.removed) {
3486 procs.add(app);
3487 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3488 app.removed = true;
3489 procs.add(app);
3490 }
3491 }
3492 }
3493
3494 int N = procs.size();
3495 for (int i=0; i<N; i++) {
3496 removeProcessLocked(procs.get(i), false, true, "kill all background");
3497 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003498 }
3499 } finally {
3500 Binder.restoreCallingIdentity(callingId);
3501 }
3502 }
3503
3504 public void forceStopPackage(final String packageName) {
3505 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3506 != PackageManager.PERMISSION_GRANTED) {
3507 String msg = "Permission Denial: forceStopPackage() from pid="
3508 + Binder.getCallingPid()
3509 + ", uid=" + Binder.getCallingUid()
3510 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003511 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003512 throw new SecurityException(msg);
3513 }
Amith Yamasani483f3b02012-03-13 16:08:00 -07003514 final int userId = UserId.getCallingUserId();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003515 long callingId = Binder.clearCallingIdentity();
3516 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003517 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003518 int pkgUid = -1;
3519 synchronized(this) {
3520 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003521 pkgUid = pm.getPackageUid(packageName, userId);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003522 } catch (RemoteException e) {
3523 }
3524 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003525 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003526 return;
3527 }
3528 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003529 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003530 pm.setPackageStoppedState(packageName, true, userId);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003531 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003532 } catch (IllegalArgumentException e) {
3533 Slog.w(TAG, "Failed trying to unstop package "
3534 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 }
3537 } finally {
3538 Binder.restoreCallingIdentity(callingId);
3539 }
3540 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003541
3542 /*
3543 * The pkg name and uid have to be specified.
3544 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3545 */
3546 public void killApplicationWithUid(String pkg, int uid) {
3547 if (pkg == null) {
3548 return;
3549 }
3550 // Make sure the uid is valid.
3551 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003552 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003553 return;
3554 }
3555 int callerUid = Binder.getCallingUid();
3556 // Only the system server can kill an application
3557 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003558 // Post an aysnc message to kill the application
3559 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3560 msg.arg1 = uid;
3561 msg.arg2 = 0;
3562 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003563 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003564 } else {
3565 throw new SecurityException(callerUid + " cannot kill pkg: " +
3566 pkg);
3567 }
3568 }
3569
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003570 public void closeSystemDialogs(String reason) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003571 enforceNotIsolatedCaller("closeSystemDialogs");
Dianne Hackborne302a162012-05-15 14:58:32 -07003572
3573 final int uid = Binder.getCallingUid();
3574 final long origId = Binder.clearCallingIdentity();
3575 synchronized (this) {
3576 closeSystemDialogsLocked(uid, reason);
3577 }
3578 Binder.restoreCallingIdentity(origId);
3579 }
3580
3581 void closeSystemDialogsLocked(int callingUid, String reason) {
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003582 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003583 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003584 if (reason != null) {
3585 intent.putExtra("reason", reason);
3586 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003587 mWindowManager.closeSystemDialogs(reason);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003588
Dianne Hackborne302a162012-05-15 14:58:32 -07003589 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3590 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn1927ae82012-06-22 15:21:36 -07003591 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborne302a162012-05-15 14:58:32 -07003592 r.stack.finishActivityLocked(r, i,
3593 Activity.RESULT_CANCELED, null, "close-sys");
Dianne Hackbornffa42482009-09-23 22:20:11 -07003594 }
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003595 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003596
3597 broadcastIntentLocked(null, null, intent, null,
3598 null, 0, null, null, null, false, false, -1,
3599 callingUid, 0 /* TODO: Verify */);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003600 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003601
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003602 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003603 throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003604 enforceNotIsolatedCaller("getProcessMemoryInfo");
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003605 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3606 for (int i=pids.length-1; i>=0; i--) {
3607 infos[i] = new Debug.MemoryInfo();
3608 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003609 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003610 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003611 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003612
Dianne Hackbornb437e092011-08-05 17:50:29 -07003613 public long[] getProcessPss(int[] pids) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003614 enforceNotIsolatedCaller("getProcessPss");
Dianne Hackbornb437e092011-08-05 17:50:29 -07003615 long[] pss = new long[pids.length];
3616 for (int i=pids.length-1; i>=0; i--) {
3617 pss[i] = Debug.getPss(pids[i]);
3618 }
3619 return pss;
3620 }
3621
Christopher Tate5e1ab332009-09-01 20:32:49 -07003622 public void killApplicationProcess(String processName, int uid) {
3623 if (processName == null) {
3624 return;
3625 }
3626
3627 int callerUid = Binder.getCallingUid();
3628 // Only the system server can kill an application
3629 if (callerUid == Process.SYSTEM_UID) {
3630 synchronized (this) {
3631 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003632 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003633 try {
3634 app.thread.scheduleSuicide();
3635 } catch (RemoteException e) {
3636 // If the other end already died, then our work here is done.
3637 }
3638 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003639 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003640 + processName + " / " + uid);
3641 }
3642 }
3643 } else {
3644 throw new SecurityException(callerUid + " cannot kill app process: " +
3645 processName);
3646 }
3647 }
3648
Dianne Hackborn03abb812010-01-04 18:43:19 -08003649 private void forceStopPackageLocked(final String packageName, int uid) {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003650 forceStopPackageLocked(packageName, uid, false, false, true, false, UserId.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003651 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3652 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003653 if (!mProcessesReady) {
3654 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003656 intent.putExtra(Intent.EXTRA_UID, uid);
3657 broadcastIntentLocked(null, null, intent,
3658 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07003659 false, false,
3660 MY_PID, Process.SYSTEM_UID, UserId.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003661 }
3662
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003663 private final boolean killPackageProcessesLocked(String packageName, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003664 int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003665 boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003666 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667
Dianne Hackborn03abb812010-01-04 18:43:19 -08003668 // Remove all processes this package may have touched: all with the
3669 // same UID (except for the system or root user), and all whose name
3670 // matches the package name.
3671 final String procNamePrefix = packageName + ":";
3672 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3673 final int NA = apps.size();
3674 for (int ia=0; ia<NA; ia++) {
3675 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003676 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003677 // we don't kill persistent processes
3678 continue;
3679 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003680 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003681 if (doit) {
3682 procs.add(app);
3683 }
Amith Yamasani13593602012-03-22 16:16:17 -07003684 // If uid is specified and the uid and process name match
3685 // Or, the uid is not specified and the process name matches
3686 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
Amith Yamasani34db3d62012-04-02 16:35:19 -07003687 || ((app.processName.equals(packageName)
3688 || app.processName.startsWith(procNamePrefix))
3689 && uid < 0))) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003690 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003691 if (!doit) {
3692 return true;
3693 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003694 app.removed = true;
3695 procs.add(app);
3696 }
3697 }
3698 }
3699 }
3700
3701 int N = procs.size();
3702 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003703 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003704 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003705 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003706 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003707
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003708 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003709 boolean callerWillRestart, boolean purgeCache, boolean doit,
Amith Yamasani483f3b02012-03-13 16:08:00 -07003710 boolean evenPersistent, int userId) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003711 int i;
3712 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 if (uid < 0) {
3715 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003716 uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003717 } catch (RemoteException e) {
3718 }
3719 }
3720
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003721 if (doit) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003722 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003723
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003724 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3725 while (badApps.hasNext()) {
3726 SparseArray<Long> ba = badApps.next();
3727 if (ba.get(uid) != null) {
3728 badApps.remove();
3729 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003730 }
3731 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003732
3733 boolean didSomething = killPackageProcessesLocked(name, uid, -100,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003734 callerWillRestart, false, doit, evenPersistent, "force stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003736 TaskRecord lastTask = null;
3737 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003738 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003739 final boolean samePackage = r.packageName.equals(name);
Amith Yamasani13593602012-03-22 16:16:17 -07003740 if (r.userId == userId
3741 && (samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003742 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003743 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003744 if (r.finishing) {
3745 // If this activity is just finishing, then it is not
3746 // interesting as far as something to stop.
3747 continue;
3748 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003749 return true;
3750 }
3751 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003752 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003753 if (samePackage) {
3754 if (r.app != null) {
3755 r.app.removed = true;
3756 }
3757 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003758 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003759 lastTask = r.task;
3760 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003761 null, "force-stop", true)) {
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003762 i--;
3763 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 }
3765 }
3766
3767 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Amith Yamasani742a6712011-05-04 14:49:28 -07003768 for (ServiceRecord service : mServiceMap.getAllServices(userId)) {
Christopher Tate064d8422011-07-26 15:38:07 -07003769 if (service.packageName.equals(name)
Christopher Tate3dacd842011-08-19 14:56:15 -07003770 && (service.app == null || evenPersistent || !service.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003771 if (!doit) {
3772 return true;
3773 }
3774 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003775 Slog.i(TAG, " Force stopping service " + service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003776 if (service.app != null) {
3777 service.app.removed = true;
3778 }
3779 service.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003780 service.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003781 services.add(service);
3782 }
3783 }
3784
3785 N = services.size();
3786 for (i=0; i<N; i++) {
3787 bringDownServiceLocked(services.get(i), true);
3788 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003789
3790 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
Amith Yamasani13593602012-03-22 16:16:17 -07003791 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003792 if (provider.info.packageName.equals(name)
3793 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3794 if (!doit) {
3795 return true;
3796 }
3797 didSomething = true;
3798 providers.add(provider);
3799 }
3800 }
3801
3802 N = providers.size();
3803 for (i=0; i<N; i++) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003804 removeDyingProviderLocked(null, providers.get(i), true);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003805 }
3806
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003807 if (doit) {
3808 if (purgeCache) {
3809 AttributeCache ac = AttributeCache.instance();
3810 if (ac != null) {
3811 ac.removePackage(name);
3812 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003813 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003814 if (mBooted) {
3815 mMainStack.resumeTopActivityLocked(null);
3816 mMainStack.scheduleIdleLocked();
3817 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003818 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003819
3820 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821 }
3822
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003823 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003824 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003825 final String name = app.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003826 final int uid = app.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003827 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003828 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003829 + "/" + uid + ")");
3830
3831 mProcessNames.remove(name, uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003832 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003833 if (mHeavyWeightProcess == app) {
3834 mHeavyWeightProcess = null;
3835 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003837 boolean needRestart = false;
3838 if (app.pid > 0 && app.pid != MY_PID) {
3839 int pid = app.pid;
3840 synchronized (mPidsSelfLocked) {
3841 mPidsSelfLocked.remove(pid);
3842 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3843 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003844 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003845 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003846 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003847 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003848
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003849 if (app.persistent && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003850 if (!callerWillRestart) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003851 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003852 } else {
3853 needRestart = true;
3854 }
3855 }
3856 } else {
3857 mRemovedProcesses.add(app);
3858 }
3859
3860 return needRestart;
3861 }
3862
3863 private final void processStartTimedOutLocked(ProcessRecord app) {
3864 final int pid = app.pid;
3865 boolean gone = false;
3866 synchronized (mPidsSelfLocked) {
3867 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3868 if (knownApp != null && knownApp.thread == null) {
3869 mPidsSelfLocked.remove(pid);
3870 gone = true;
3871 }
3872 }
3873
3874 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003875 Slog.w(TAG, "Process " + app + " failed to attach");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003876 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003877 app.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003878 mProcessNames.remove(app.processName, app.uid);
3879 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003880 if (mHeavyWeightProcess == app) {
3881 mHeavyWeightProcess = null;
3882 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
3883 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003884 // Take care of any launching providers waiting for this process.
3885 checkAppInLaunchingProvidersLocked(app, true);
3886 // Take care of any services that are waiting for the process.
3887 for (int i=0; i<mPendingServices.size(); i++) {
3888 ServiceRecord sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003889 if ((app.uid == sr.appInfo.uid
3890 && app.processName.equals(sr.processName))
3891 || sr.isolatedProc == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003892 Slog.w(TAG, "Forcing bringing down service: " + sr);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003893 sr.isolatedProc = null;
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003894 mPendingServices.remove(i);
3895 i--;
3896 bringDownServiceLocked(sr, true);
3897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003898 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003899 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3900 app.processName, app.setAdj, "start timeout");
3901 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003902 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003903 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003904 try {
3905 IBackupManager bm = IBackupManager.Stub.asInterface(
3906 ServiceManager.getService(Context.BACKUP_SERVICE));
3907 bm.agentDisconnected(app.info.packageName);
3908 } catch (RemoteException e) {
3909 // Can't happen; the backup manager is local
3910 }
3911 }
Christopher Tatef46723b2012-01-26 14:19:24 -08003912 if (isPendingBroadcastProcessLocked(pid)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003913 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Christopher Tatef46723b2012-01-26 14:19:24 -08003914 skipPendingBroadcastLocked(pid);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003915 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003916 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003917 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 }
3919 }
3920
3921 private final boolean attachApplicationLocked(IApplicationThread thread,
3922 int pid) {
3923
3924 // Find the application record that is being attached... either via
3925 // the pid if we are running in multiple processes, or just pull the
3926 // next app record if we are emulating process with anonymous threads.
3927 ProcessRecord app;
3928 if (pid != MY_PID && pid >= 0) {
3929 synchronized (mPidsSelfLocked) {
3930 app = mPidsSelfLocked.get(pid);
3931 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 } else {
3933 app = null;
3934 }
3935
3936 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003937 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003938 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003939 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003941 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003942 } else {
3943 try {
3944 thread.scheduleExit();
3945 } catch (Exception e) {
3946 // Ignore exceptions.
3947 }
3948 }
3949 return false;
3950 }
3951
3952 // If this application record is still attached to a previous
3953 // process, clean it up now.
3954 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003955 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003956 }
3957
3958 // Tell the process all about itself.
3959
Joe Onorato8a9b2202010-02-26 18:56:32 -08003960 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 TAG, "Binding process pid " + pid + " to record " + app);
3962
3963 String processName = app.processName;
3964 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003965 AppDeathRecipient adr = new AppDeathRecipient(
3966 app, pid, thread);
3967 thread.asBinder().linkToDeath(adr, 0);
3968 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 } catch (RemoteException e) {
3970 app.resetPackageList();
3971 startProcessLocked(app, "link fail", processName);
3972 return false;
3973 }
3974
Doug Zongker2bec3d42009-12-04 12:52:44 -08003975 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976
3977 app.thread = thread;
3978 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08003979 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
3980 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003981 app.forcingToForeground = null;
3982 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07003983 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003984 app.debugging = false;
3985
3986 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3987
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003988 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003989 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003991 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003992 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07003993 }
3994
Joe Onorato8a9b2202010-02-26 18:56:32 -08003995 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003996 TAG, "New app record " + app
3997 + " thread=" + thread.asBinder() + " pid=" + pid);
3998 try {
3999 int testMode = IApplicationThread.DEBUG_OFF;
4000 if (mDebugApp != null && mDebugApp.equals(processName)) {
4001 testMode = mWaitForDebugger
4002 ? IApplicationThread.DEBUG_WAIT
4003 : IApplicationThread.DEBUG_ON;
4004 app.debugging = true;
4005 if (mDebugTransient) {
4006 mDebugApp = mOrigDebugApp;
4007 mWaitForDebugger = mOrigWaitForDebugger;
4008 }
4009 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004010 String profileFile = app.instrumentationProfileFile;
4011 ParcelFileDescriptor profileFd = null;
4012 boolean profileAutoStop = false;
4013 if (mProfileApp != null && mProfileApp.equals(processName)) {
4014 mProfileProc = app;
4015 profileFile = mProfileFile;
4016 profileFd = mProfileFd;
4017 profileAutoStop = mAutoStopProfiler;
4018 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08004019 boolean enableOpenGlTrace = false;
4020 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4021 enableOpenGlTrace = true;
4022 mOpenGlTraceApp = null;
4023 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004024
Christopher Tate181fafa2009-05-14 11:12:14 -07004025 // If the app is being launched for restore or full backup, set it up specially
4026 boolean isRestrictedBackupMode = false;
4027 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4028 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07004029 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07004030 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4031 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004032
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07004033 ensurePackageDexOpt(app.instrumentationInfo != null
4034 ? app.instrumentationInfo.packageName
4035 : app.info.packageName);
4036 if (app.instrumentationClass != null) {
4037 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004038 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004039 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07004040 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004041 ApplicationInfo appInfo = app.instrumentationInfo != null
4042 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07004043 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004044 if (profileFd != null) {
4045 profileFd = profileFd.dup();
4046 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004047 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004048 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
Siva Velusamy92a8b222012-03-09 16:24:04 -08004049 app.instrumentationArguments, app.instrumentationWatcher, testMode,
4050 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08004051 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004052 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004053 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07004054 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055 } catch (Exception e) {
4056 // todo: Yikes! What should we do? For now we will try to
4057 // start another process, but that could easily get us in
4058 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08004059 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004060
4061 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004062 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 startProcessLocked(app, "bind fail", processName);
4064 return false;
4065 }
4066
4067 // Remove this record from the list of starting applications.
4068 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004069 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4070 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004071 mProcessesOnHold.remove(app);
4072
4073 boolean badApp = false;
4074 boolean didSomething = false;
4075
4076 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004077 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07004078 if (hr != null && normalMode) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004079 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004080 && processName.equals(hr.processName)) {
4081 try {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07004082 if (mHeadless) {
4083 Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4084 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004085 didSomething = true;
4086 }
4087 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004088 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 + hr.intent.getComponent().flattenToShortString(), e);
4090 badApp = true;
4091 }
4092 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004093 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 }
4095 }
4096
4097 // Find any services that should be running in this process...
4098 if (!badApp && mPendingServices.size() > 0) {
4099 ServiceRecord sr = null;
4100 try {
4101 for (int i=0; i<mPendingServices.size(); i++) {
4102 sr = mPendingServices.get(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004103 if (app != sr.isolatedProc && (app.uid != sr.appInfo.uid
4104 || !processName.equals(sr.processName))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004105 continue;
4106 }
4107
4108 mPendingServices.remove(i);
4109 i--;
4110 realStartServiceLocked(sr, app);
4111 didSomething = true;
4112 }
4113 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004114 Slog.w(TAG, "Exception in new application when starting service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004115 + sr.shortName, e);
4116 badApp = true;
4117 }
4118 }
4119
Christopher Tatef46723b2012-01-26 14:19:24 -08004120 // Check if a next-broadcast receiver is in this process...
4121 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 try {
Christopher Tatef46723b2012-01-26 14:19:24 -08004123 didSomething = sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004124 } catch (Exception e) {
Christopher Tatef46723b2012-01-26 14:19:24 -08004125 // If the app died trying to launch the receiver we declare it 'bad'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 badApp = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004127 }
4128 }
4129
Christopher Tate181fafa2009-05-14 11:12:14 -07004130 // Check whether the next backup agent is in this process...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004131 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004132 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004133 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07004134 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004135 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4136 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4137 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07004138 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004139 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07004140 e.printStackTrace();
4141 }
4142 }
4143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004144 if (badApp) {
4145 // todo: Also need to kill application to deal with all
4146 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004147 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004148 return false;
4149 }
4150
4151 if (!didSomething) {
4152 updateOomAdjLocked();
4153 }
4154
4155 return true;
4156 }
4157
4158 public final void attachApplication(IApplicationThread thread) {
4159 synchronized (this) {
4160 int callingPid = Binder.getCallingPid();
4161 final long origId = Binder.clearCallingIdentity();
4162 attachApplicationLocked(thread, callingPid);
4163 Binder.restoreCallingIdentity(origId);
4164 }
4165 }
4166
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004167 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004169 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4170 if (stopProfiling) {
4171 synchronized (this) {
4172 if (mProfileProc == r.app) {
4173 if (mProfileFd != null) {
4174 try {
4175 mProfileFd.close();
4176 } catch (IOException e) {
4177 }
4178 clearProfilerLocked();
4179 }
4180 }
4181 }
4182 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 Binder.restoreCallingIdentity(origId);
4184 }
4185
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004186 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004187 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004188 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 mWindowManager.enableScreenAfterBoot();
Jeff Brownc042ee22012-05-08 13:03:42 -07004190
4191 synchronized (this) {
4192 updateEventDispatchingLocked();
4193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 }
4195
Dianne Hackborn661cd522011-08-22 00:26:20 -07004196 public void showBootMessage(final CharSequence msg, final boolean always) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004197 enforceNotIsolatedCaller("showBootMessage");
Dianne Hackborn661cd522011-08-22 00:26:20 -07004198 mWindowManager.showBootMessage(msg, always);
4199 }
4200
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004201 public void dismissKeyguardOnNextActivity() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004202 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
Jeff Sharkey7ffaa982012-04-30 16:59:05 -07004203 final long token = Binder.clearCallingIdentity();
4204 try {
4205 synchronized (this) {
4206 if (mLockScreenShown) {
4207 mLockScreenShown = false;
4208 comeOutOfSleepIfNeededLocked();
4209 }
4210 mMainStack.dismissKeyguardOnNextActivityLocked();
Dianne Hackborn1e88e982012-04-24 18:35:55 -07004211 }
Jeff Sharkey7ffaa982012-04-30 16:59:05 -07004212 } finally {
4213 Binder.restoreCallingIdentity(token);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004214 }
4215 }
4216
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004217 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004218 IntentFilter pkgFilter = new IntentFilter();
4219 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4220 pkgFilter.addDataScheme("package");
4221 mContext.registerReceiver(new BroadcastReceiver() {
4222 @Override
4223 public void onReceive(Context context, Intent intent) {
4224 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4225 if (pkgs != null) {
4226 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004227 synchronized (ActivityManagerService.this) {
Amith Yamasani483f3b02012-03-13 16:08:00 -07004228 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4229 setResultCode(Activity.RESULT_OK);
4230 return;
4231 }
4232 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004233 }
4234 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004235 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004236 }, pkgFilter);
Amith Yamasani13593602012-03-22 16:16:17 -07004237
4238 IntentFilter userFilter = new IntentFilter();
4239 userFilter.addAction(Intent.ACTION_USER_REMOVED);
4240 mContext.registerReceiver(new BroadcastReceiver() {
4241 @Override
4242 public void onReceive(Context context, Intent intent) {
4243 onUserRemoved(intent);
4244 }
4245 }, userFilter);
4246
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004247 synchronized (this) {
4248 // Ensure that any processes we had put on hold are now started
4249 // up.
4250 final int NP = mProcessesOnHold.size();
4251 if (NP > 0) {
4252 ArrayList<ProcessRecord> procs =
4253 new ArrayList<ProcessRecord>(mProcessesOnHold);
4254 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004255 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4256 + procs.get(ip));
4257 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004258 }
4259 }
4260
4261 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004262 // Start looking for apps that are abusing wake locks.
4263 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004264 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004265 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004266 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004267 SystemProperties.set("dev.bootcomplete", "1");
Amith Yamasani742a6712011-05-04 14:49:28 -07004268 /* TODO: Send this to all users that are to be logged in on startup */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004269 broadcastIntentLocked(null, null,
4270 new Intent(Intent.ACTION_BOOT_COMPLETED, null),
4271 null, null, 0, null, null,
4272 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Amith Yamasani742a6712011-05-04 14:49:28 -07004273 false, false, MY_PID, Process.SYSTEM_UID, Binder.getOrigCallingUser());
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004274 }
4275 }
4276 }
4277
4278 final void ensureBootCompleted() {
4279 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004280 boolean enableScreen;
4281 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004282 booting = mBooting;
4283 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004284 enableScreen = !mBooted;
4285 mBooted = true;
4286 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004287
4288 if (booting) {
4289 finishBooting();
4290 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004291
4292 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004293 enableScreenAfterBoot();
4294 }
4295 }
4296
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004297 public final void activityPaused(IBinder token) {
4298 final long origId = Binder.clearCallingIdentity();
4299 mMainStack.activityPaused(token, false);
4300 Binder.restoreCallingIdentity(origId);
4301 }
4302
4303 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4304 CharSequence description) {
4305 if (localLOGV) Slog.v(
4306 TAG, "Activity stopped: token=" + token);
4307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004308 // Refuse possible leaked file descriptors
4309 if (icicle != null && icicle.hasFileDescriptors()) {
4310 throw new IllegalArgumentException("File descriptors passed in Bundle");
4311 }
4312
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004313 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004314
4315 final long origId = Binder.clearCallingIdentity();
4316
4317 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004318 r = mMainStack.isInStackLocked(token);
4319 if (r != null) {
4320 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004321 }
4322 }
4323
4324 if (r != null) {
4325 sendPendingThumbnail(r, null, null, null, false);
4326 }
4327
4328 trimApplications();
4329
4330 Binder.restoreCallingIdentity(origId);
4331 }
4332
4333 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004334 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004335 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336 }
4337
4338 public String getCallingPackage(IBinder token) {
4339 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004340 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004341 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004342 }
4343 }
4344
4345 public ComponentName getCallingActivity(IBinder token) {
4346 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004347 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004348 return r != null ? r.intent.getComponent() : null;
4349 }
4350 }
4351
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004352 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004353 ActivityRecord r = mMainStack.isInStackLocked(token);
4354 if (r == null) {
4355 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004356 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004357 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004358 }
4359
4360 public ComponentName getActivityClassForToken(IBinder token) {
4361 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004362 ActivityRecord r = mMainStack.isInStackLocked(token);
4363 if (r == null) {
4364 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004365 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004366 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367 }
4368 }
4369
4370 public String getPackageForToken(IBinder token) {
4371 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004372 ActivityRecord r = mMainStack.isInStackLocked(token);
4373 if (r == null) {
4374 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004375 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004376 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 }
4378 }
4379
4380 public IIntentSender getIntentSender(int type,
4381 String packageName, IBinder token, String resultWho,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004382 int requestCode, Intent[] intents, String[] resolvedTypes,
4383 int flags, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004384 enforceNotIsolatedCaller("getIntentSender");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004386 if (intents != null) {
4387 if (intents.length < 1) {
4388 throw new IllegalArgumentException("Intents array length must be >= 1");
4389 }
4390 for (int i=0; i<intents.length; i++) {
4391 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004392 if (intent != null) {
4393 if (intent.hasFileDescriptors()) {
4394 throw new IllegalArgumentException("File descriptors passed in Intent");
4395 }
Dianne Hackborna4972e92012-03-14 10:38:05 -07004396 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004397 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4398 throw new IllegalArgumentException(
4399 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4400 }
4401 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004402 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004403 }
4404 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004405 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004406 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004407 }
4408 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004409 if (options != null) {
4410 if (options.hasFileDescriptors()) {
4411 throw new IllegalArgumentException("File descriptors passed in options");
4412 }
4413 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 synchronized(this) {
4416 int callingUid = Binder.getCallingUid();
4417 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004418 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004419 int uid = AppGlobals.getPackageManager()
Amith Yamasani483f3b02012-03-13 16:08:00 -07004420 .getPackageUid(packageName, UserId.getUserId(callingUid));
4421 if (!UserId.isSameApp(callingUid, uid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004422 String msg = "Permission Denial: getIntentSender() from pid="
4423 + Binder.getCallingPid()
4424 + ", uid=" + Binder.getCallingUid()
4425 + ", (need uid=" + uid + ")"
4426 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004427 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004428 throw new SecurityException(msg);
4429 }
4430 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004431
Amith Yamasani742a6712011-05-04 14:49:28 -07004432 if (DEBUG_MU)
4433 Slog.i(TAG_MU, "Getting intent sender for origCallingUid="
4434 + Binder.getOrigCallingUid());
4435 return getIntentSenderLocked(type, packageName, Binder.getOrigCallingUid(),
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004436 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004438 } catch (RemoteException e) {
4439 throw new SecurityException(e);
4440 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004441 }
4442 }
4443
4444 IIntentSender getIntentSenderLocked(int type,
4445 String packageName, int callingUid, IBinder token, String resultWho,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004446 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4447 Bundle options) {
Amith Yamasani742a6712011-05-04 14:49:28 -07004448 if (DEBUG_MU)
4449 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004450 ActivityRecord activity = null;
Dianne Hackborna4972e92012-03-14 10:38:05 -07004451 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004452 activity = mMainStack.isInStackLocked(token);
4453 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004454 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004455 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004456 if (activity.finishing) {
4457 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004458 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004459 }
4460
4461 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4462 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4463 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4464 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4465 |PendingIntent.FLAG_UPDATE_CURRENT);
4466
4467 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4468 type, packageName, activity, resultWho,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004469 requestCode, intents, resolvedTypes, flags, options);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004470 WeakReference<PendingIntentRecord> ref;
4471 ref = mIntentSenderRecords.get(key);
4472 PendingIntentRecord rec = ref != null ? ref.get() : null;
4473 if (rec != null) {
4474 if (!cancelCurrent) {
4475 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004476 if (rec.key.requestIntent != null) {
Adam Powell501d4a52012-04-30 15:03:57 -07004477 rec.key.requestIntent.replaceExtras(intents != null ?
4478 intents[intents.length - 1] : null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004479 }
4480 if (intents != null) {
4481 intents[intents.length-1] = rec.key.requestIntent;
4482 rec.key.allIntents = intents;
4483 rec.key.allResolvedTypes = resolvedTypes;
4484 } else {
4485 rec.key.allIntents = null;
4486 rec.key.allResolvedTypes = null;
4487 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004489 return rec;
4490 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004491 rec.canceled = true;
4492 mIntentSenderRecords.remove(key);
4493 }
4494 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004495 return rec;
4496 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004497 rec = new PendingIntentRecord(this, key, callingUid);
4498 mIntentSenderRecords.put(key, rec.ref);
Dianne Hackborna4972e92012-03-14 10:38:05 -07004499 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004500 if (activity.pendingResults == null) {
4501 activity.pendingResults
4502 = new HashSet<WeakReference<PendingIntentRecord>>();
4503 }
4504 activity.pendingResults.add(rec.ref);
4505 }
4506 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004507 }
4508
4509 public void cancelIntentSender(IIntentSender sender) {
4510 if (!(sender instanceof PendingIntentRecord)) {
4511 return;
4512 }
4513 synchronized(this) {
4514 PendingIntentRecord rec = (PendingIntentRecord)sender;
4515 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004516 int uid = AppGlobals.getPackageManager()
Amith Yamasani483f3b02012-03-13 16:08:00 -07004517 .getPackageUid(rec.key.packageName, UserId.getCallingUserId());
Amith Yamasani04e0d262012-02-14 11:50:53 -08004518 if (!UserId.isSameApp(uid, Binder.getCallingUid())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004519 String msg = "Permission Denial: cancelIntentSender() from pid="
4520 + Binder.getCallingPid()
4521 + ", uid=" + Binder.getCallingUid()
4522 + " is not allowed to cancel packges "
4523 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004524 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004525 throw new SecurityException(msg);
4526 }
4527 } catch (RemoteException e) {
4528 throw new SecurityException(e);
4529 }
4530 cancelIntentSenderLocked(rec, true);
4531 }
4532 }
4533
4534 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4535 rec.canceled = true;
4536 mIntentSenderRecords.remove(rec.key);
4537 if (cleanActivity && rec.key.activity != null) {
4538 rec.key.activity.pendingResults.remove(rec.ref);
4539 }
4540 }
4541
4542 public String getPackageForIntentSender(IIntentSender pendingResult) {
4543 if (!(pendingResult instanceof PendingIntentRecord)) {
4544 return null;
4545 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004546 try {
4547 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4548 return res.key.packageName;
4549 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004550 }
4551 return null;
4552 }
4553
Christopher Tatec4a07d12012-04-06 14:19:13 -07004554 public int getUidForIntentSender(IIntentSender sender) {
4555 if (sender instanceof PendingIntentRecord) {
4556 try {
4557 PendingIntentRecord res = (PendingIntentRecord)sender;
4558 return res.uid;
4559 } catch (ClassCastException e) {
4560 }
4561 }
4562 return -1;
4563 }
4564
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004565 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4566 if (!(pendingResult instanceof PendingIntentRecord)) {
4567 return false;
4568 }
4569 try {
4570 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4571 if (res.key.allIntents == null) {
4572 return false;
4573 }
4574 for (int i=0; i<res.key.allIntents.length; i++) {
4575 Intent intent = res.key.allIntents[i];
4576 if (intent.getPackage() != null && intent.getComponent() != null) {
4577 return false;
4578 }
4579 }
4580 return true;
4581 } catch (ClassCastException e) {
4582 }
4583 return false;
4584 }
4585
Dianne Hackborn1927ae82012-06-22 15:21:36 -07004586 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4587 if (!(pendingResult instanceof PendingIntentRecord)) {
4588 return false;
4589 }
4590 try {
4591 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4592 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4593 return true;
4594 }
4595 return false;
4596 } catch (ClassCastException e) {
4597 }
4598 return false;
4599 }
4600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004601 public void setProcessLimit(int max) {
4602 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4603 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004604 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004605 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004606 mProcessLimitOverride = max;
4607 }
4608 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004609 }
4610
4611 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004612 synchronized (this) {
4613 return mProcessLimitOverride;
4614 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004615 }
4616
4617 void foregroundTokenDied(ForegroundToken token) {
4618 synchronized (ActivityManagerService.this) {
4619 synchronized (mPidsSelfLocked) {
4620 ForegroundToken cur
4621 = mForegroundProcesses.get(token.pid);
4622 if (cur != token) {
4623 return;
4624 }
4625 mForegroundProcesses.remove(token.pid);
4626 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4627 if (pr == null) {
4628 return;
4629 }
4630 pr.forcingToForeground = null;
4631 pr.foregroundServices = false;
4632 }
4633 updateOomAdjLocked();
4634 }
4635 }
4636
4637 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4638 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4639 "setProcessForeground()");
4640 synchronized(this) {
4641 boolean changed = false;
4642
4643 synchronized (mPidsSelfLocked) {
4644 ProcessRecord pr = mPidsSelfLocked.get(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004645 if (pr == null && isForeground) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004646 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004647 return;
4648 }
4649 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4650 if (oldToken != null) {
4651 oldToken.token.unlinkToDeath(oldToken, 0);
4652 mForegroundProcesses.remove(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004653 if (pr != null) {
4654 pr.forcingToForeground = null;
4655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004656 changed = true;
4657 }
4658 if (isForeground && token != null) {
4659 ForegroundToken newToken = new ForegroundToken() {
4660 public void binderDied() {
4661 foregroundTokenDied(this);
4662 }
4663 };
4664 newToken.pid = pid;
4665 newToken.token = token;
4666 try {
4667 token.linkToDeath(newToken, 0);
4668 mForegroundProcesses.put(pid, newToken);
4669 pr.forcingToForeground = token;
4670 changed = true;
4671 } catch (RemoteException e) {
4672 // If the process died while doing this, we will later
4673 // do the cleanup with the process death link.
4674 }
4675 }
4676 }
4677
4678 if (changed) {
4679 updateOomAdjLocked();
4680 }
4681 }
4682 }
4683
4684 // =========================================================
4685 // PERMISSIONS
4686 // =========================================================
4687
4688 static class PermissionController extends IPermissionController.Stub {
4689 ActivityManagerService mActivityManagerService;
4690 PermissionController(ActivityManagerService activityManagerService) {
4691 mActivityManagerService = activityManagerService;
4692 }
4693
4694 public boolean checkPermission(String permission, int pid, int uid) {
4695 return mActivityManagerService.checkPermission(permission, pid,
4696 uid) == PackageManager.PERMISSION_GRANTED;
4697 }
4698 }
4699
4700 /**
4701 * This can be called with or without the global lock held.
4702 */
4703 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004704 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 // We might be performing an operation on behalf of an indirect binder
4706 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4707 // client identity accordingly before proceeding.
4708 Identity tlsIdentity = sCallerIdentity.get();
4709 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004710 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004711 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4712 uid = tlsIdentity.uid;
4713 pid = tlsIdentity.pid;
4714 }
4715
Dianne Hackborn5320eb82012-05-18 12:05:04 -07004716 if (pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004717 return PackageManager.PERMISSION_GRANTED;
4718 }
Dianne Hackborn5320eb82012-05-18 12:05:04 -07004719
4720 return ActivityManager.checkComponentPermission(permission, uid,
4721 owningUid, exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004722 }
4723
4724 /**
4725 * As the only public entry point for permissions checking, this method
4726 * can enforce the semantic that requesting a check on a null global
4727 * permission is automatically denied. (Internally a null permission
4728 * string is used when calling {@link #checkComponentPermission} in cases
4729 * when only uid-based security is needed.)
4730 *
4731 * This can be called with or without the global lock held.
4732 */
4733 public int checkPermission(String permission, int pid, int uid) {
4734 if (permission == null) {
4735 return PackageManager.PERMISSION_DENIED;
4736 }
Amith Yamasani742a6712011-05-04 14:49:28 -07004737 return checkComponentPermission(permission, pid, UserId.getAppId(uid), -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738 }
4739
4740 /**
4741 * Binder IPC calls go through the public entry point.
4742 * This can be called with or without the global lock held.
4743 */
4744 int checkCallingPermission(String permission) {
4745 return checkPermission(permission,
4746 Binder.getCallingPid(),
Amith Yamasani742a6712011-05-04 14:49:28 -07004747 UserId.getAppId(Binder.getCallingUid()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004748 }
4749
4750 /**
4751 * This can be called with or without the global lock held.
4752 */
4753 void enforceCallingPermission(String permission, String func) {
4754 if (checkCallingPermission(permission)
4755 == PackageManager.PERMISSION_GRANTED) {
4756 return;
4757 }
4758
4759 String msg = "Permission Denial: " + func + " from pid="
4760 + Binder.getCallingPid()
4761 + ", uid=" + Binder.getCallingUid()
4762 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004763 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004764 throw new SecurityException(msg);
4765 }
4766
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004767 /**
4768 * Determine if UID is holding permissions required to access {@link Uri} in
4769 * the given {@link ProviderInfo}. Final permission checking is always done
4770 * in {@link ContentProvider}.
4771 */
4772 private final boolean checkHoldingPermissionsLocked(
4773 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004774 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4775 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004776
4777 if (pi.applicationInfo.uid == uid) {
4778 return true;
4779 } else if (!pi.exported) {
4780 return false;
4781 }
4782
4783 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4784 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004785 try {
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004786 // check if target holds top-level <provider> permissions
4787 if (!readMet && pi.readPermission != null
4788 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4789 readMet = true;
4790 }
4791 if (!writeMet && pi.writePermission != null
4792 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4793 writeMet = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004794 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004795
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004796 // track if unprotected read/write is allowed; any denied
4797 // <path-permission> below removes this ability
4798 boolean allowDefaultRead = pi.readPermission == null;
4799 boolean allowDefaultWrite = pi.writePermission == null;
Dianne Hackborn48058e82010-09-27 16:53:23 -07004800
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004801 // check if target holds any <path-permission> that match uri
4802 final PathPermission[] pps = pi.pathPermissions;
4803 if (pps != null) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004804 final String path = uri.getPath();
4805 int i = pps.length;
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004806 while (i > 0 && (!readMet || !writeMet)) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004807 i--;
4808 PathPermission pp = pps[i];
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004809 if (pp.match(path)) {
4810 if (!readMet) {
4811 final String pprperm = pp.getReadPermission();
4812 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4813 + pprperm + " for " + pp.getPath()
4814 + ": match=" + pp.match(path)
4815 + " check=" + pm.checkUidPermission(pprperm, uid));
4816 if (pprperm != null) {
4817 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4818 readMet = true;
4819 } else {
4820 allowDefaultRead = false;
4821 }
4822 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004823 }
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004824 if (!writeMet) {
4825 final String ppwperm = pp.getWritePermission();
4826 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4827 + ppwperm + " for " + pp.getPath()
4828 + ": match=" + pp.match(path)
4829 + " check=" + pm.checkUidPermission(ppwperm, uid));
4830 if (ppwperm != null) {
4831 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4832 writeMet = true;
4833 } else {
4834 allowDefaultWrite = false;
4835 }
4836 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004837 }
4838 }
4839 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004840 }
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004841
4842 // grant unprotected <provider> read/write, if not blocked by
4843 // <path-permission> above
4844 if (allowDefaultRead) readMet = true;
4845 if (allowDefaultWrite) writeMet = true;
4846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004847 } catch (RemoteException e) {
4848 return false;
4849 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004850
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004851 return readMet && writeMet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004852 }
4853
4854 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4855 int modeFlags) {
4856 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004857 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004858 return true;
4859 }
4860 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4861 if (perms == null) return false;
4862 UriPermission perm = perms.get(uri);
4863 if (perm == null) return false;
4864 return (modeFlags&perm.modeFlags) == modeFlags;
4865 }
4866
4867 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004868 enforceNotIsolatedCaller("checkUriPermission");
4869
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 // Another redirected-binder-call permissions check as in
4871 // {@link checkComponentPermission}.
4872 Identity tlsIdentity = sCallerIdentity.get();
4873 if (tlsIdentity != null) {
4874 uid = tlsIdentity.uid;
4875 pid = tlsIdentity.pid;
4876 }
4877
Amith Yamasani742a6712011-05-04 14:49:28 -07004878 uid = UserId.getAppId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004879 // Our own process gets to do everything.
4880 if (pid == MY_PID) {
4881 return PackageManager.PERMISSION_GRANTED;
4882 }
4883 synchronized(this) {
4884 return checkUriPermissionLocked(uri, uid, modeFlags)
4885 ? PackageManager.PERMISSION_GRANTED
4886 : PackageManager.PERMISSION_DENIED;
4887 }
4888 }
4889
Dianne Hackborn39792d22010-08-19 18:01:52 -07004890 /**
4891 * Check if the targetPkg can be granted permission to access uri by
4892 * the callingUid using the given modeFlags. Throws a security exception
4893 * if callingUid is not allowed to do this. Returns the uid of the target
4894 * if the URI permission grant should be performed; returns -1 if it is not
4895 * needed (for example targetPkg already has permission to access the URI).
Dianne Hackborn21c241e2012-03-08 13:57:23 -08004896 * If you already know the uid of the target, you can supply it in
4897 * lastTargetUid else set that to -1.
Dianne Hackborn39792d22010-08-19 18:01:52 -07004898 */
4899 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
Dianne Hackborn21c241e2012-03-08 13:57:23 -08004900 Uri uri, int modeFlags, int lastTargetUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004901 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4902 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4903 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004904 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004905 }
4906
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004907 if (targetPkg != null) {
4908 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4909 "Checking grant " + targetPkg + " permission to " + uri);
4910 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004911
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004912 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913
4914 // If this is not a content: uri, we can't do anything with it.
4915 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004916 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004917 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004918 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 }
4920
4921 String name = uri.getAuthority();
4922 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07004923 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
4924 UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925 if (cpr != null) {
4926 pi = cpr.info;
4927 } else {
4928 try {
4929 pi = pm.resolveContentProvider(name,
Amith Yamasani483f3b02012-03-13 16:08:00 -07004930 PackageManager.GET_URI_PERMISSION_PATTERNS, UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004931 } catch (RemoteException ex) {
4932 }
4933 }
4934 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004935 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004936 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004937 }
4938
Dianne Hackborn21c241e2012-03-08 13:57:23 -08004939 int targetUid = lastTargetUid;
4940 if (targetUid < 0 && targetPkg != null) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004941 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07004942 targetUid = pm.getPackageUid(targetPkg, UserId.getUserId(callingUid));
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004943 if (targetUid < 0) {
4944 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4945 "Can't grant URI permission no uid for: " + targetPkg);
4946 return -1;
4947 }
4948 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004949 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004950 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004951 }
4952
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004953 if (targetUid >= 0) {
4954 // First... does the target actually need this permission?
4955 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4956 // No need to grant the target this permission.
4957 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4958 "Target " + targetPkg + " already has full permission to " + uri);
4959 return -1;
4960 }
4961 } else {
4962 // First... there is no target package, so can anyone access it?
4963 boolean allowed = pi.exported;
4964 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4965 if (pi.readPermission != null) {
4966 allowed = false;
4967 }
4968 }
4969 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4970 if (pi.writePermission != null) {
4971 allowed = false;
4972 }
4973 }
4974 if (allowed) {
4975 return -1;
4976 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004977 }
4978
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004979 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004980 if (!pi.grantUriPermissions) {
4981 throw new SecurityException("Provider " + pi.packageName
4982 + "/" + pi.name
4983 + " does not allow granting of Uri permissions (uri "
4984 + uri + ")");
4985 }
4986 if (pi.uriPermissionPatterns != null) {
4987 final int N = pi.uriPermissionPatterns.length;
4988 boolean allowed = false;
4989 for (int i=0; i<N; i++) {
4990 if (pi.uriPermissionPatterns[i] != null
4991 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
4992 allowed = true;
4993 break;
4994 }
4995 }
4996 if (!allowed) {
4997 throw new SecurityException("Provider " + pi.packageName
4998 + "/" + pi.name
4999 + " does not allow granting of permission to path of Uri "
5000 + uri);
5001 }
5002 }
5003
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005004 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005005 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005006 if (callingUid != Process.myUid()) {
5007 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5008 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5009 throw new SecurityException("Uid " + callingUid
5010 + " does not have permission to uri " + uri);
5011 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005012 }
5013 }
5014
Dianne Hackborn39792d22010-08-19 18:01:52 -07005015 return targetUid;
5016 }
5017
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005018 public int checkGrantUriPermission(int callingUid, String targetPkg,
5019 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005020 enforceNotIsolatedCaller("checkGrantUriPermission");
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005021 synchronized(this) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005022 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005023 }
5024 }
5025
Dianne Hackborn39792d22010-08-19 18:01:52 -07005026 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5027 Uri uri, int modeFlags, UriPermissionOwner owner) {
5028 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5029 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5030 if (modeFlags == 0) {
5031 return;
5032 }
5033
5034 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005035 // to the uri, and the target doesn't. Let's now give this to
5036 // the target.
5037
Joe Onorato8a9b2202010-02-26 18:56:32 -08005038 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005039 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 HashMap<Uri, UriPermission> targetUris
5042 = mGrantedUriPermissions.get(targetUid);
5043 if (targetUris == null) {
5044 targetUris = new HashMap<Uri, UriPermission>();
5045 mGrantedUriPermissions.put(targetUid, targetUris);
5046 }
5047
5048 UriPermission perm = targetUris.get(uri);
5049 if (perm == null) {
5050 perm = new UriPermission(targetUid, uri);
5051 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005052 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005054 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005055 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005056 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08005057 } else {
5058 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5059 perm.readOwners.add(owner);
5060 owner.addReadPermission(perm);
5061 }
5062 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5063 perm.writeOwners.add(owner);
5064 owner.addWritePermission(perm);
5065 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005066 }
5067 }
5068
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005069 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5070 int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005071 if (targetPkg == null) {
5072 throw new NullPointerException("targetPkg");
5073 }
5074
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005075 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005076 if (targetUid < 0) {
5077 return;
5078 }
5079
5080 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5081 }
5082
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005083 static class NeededUriGrants extends ArrayList<Uri> {
5084 final String targetPkg;
5085 final int targetUid;
5086 final int flags;
5087
5088 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5089 targetPkg = _targetPkg;
5090 targetUid = _targetUid;
5091 flags = _flags;
5092 }
5093 }
5094
Dianne Hackborn39792d22010-08-19 18:01:52 -07005095 /**
5096 * Like checkGrantUriPermissionLocked, but takes an Intent.
5097 */
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005098 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5099 String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07005100 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005101 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5102 + " clip=" + (intent != null ? intent.getClipData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005103 + " from " + intent + "; flags=0x"
5104 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5105
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005106 if (targetPkg == null) {
5107 throw new NullPointerException("targetPkg");
5108 }
5109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005110 if (intent == null) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005111 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005112 }
5113 Uri data = intent.getData();
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005114 ClipData clip = intent.getClipData();
5115 if (data == null && clip == null) {
5116 return null;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005117 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005118 if (data != null) {
5119 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5120 mode, needed != null ? needed.targetUid : -1);
5121 if (target > 0) {
5122 if (needed == null) {
5123 needed = new NeededUriGrants(targetPkg, target, mode);
5124 }
5125 needed.add(data);
5126 }
5127 }
5128 if (clip != null) {
5129 for (int i=0; i<clip.getItemCount(); i++) {
5130 Uri uri = clip.getItemAt(i).getUri();
5131 if (uri != null) {
5132 int target = -1;
5133 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5134 mode, needed != null ? needed.targetUid : -1);
5135 if (target > 0) {
5136 if (needed == null) {
5137 needed = new NeededUriGrants(targetPkg, target, mode);
5138 }
5139 needed.add(uri);
5140 }
5141 } else {
5142 Intent clipIntent = clip.getItemAt(i).getIntent();
5143 if (clipIntent != null) {
5144 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5145 callingUid, targetPkg, clipIntent, mode, needed);
5146 if (newNeeded != null) {
5147 needed = newNeeded;
5148 }
5149 }
5150 }
5151 }
5152 }
5153
5154 return needed;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005155 }
5156
5157 /**
5158 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5159 */
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005160 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5161 UriPermissionOwner owner) {
5162 if (needed != null) {
5163 for (int i=0; i<needed.size(); i++) {
5164 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5165 needed.get(i), needed.flags, owner);
5166 }
5167 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005168 }
5169
5170 void grantUriPermissionFromIntentLocked(int callingUid,
5171 String targetPkg, Intent intent, UriPermissionOwner owner) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005172 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
Dianne Hackbornd9781fe2012-03-08 18:04:18 -08005173 intent, intent != null ? intent.getFlags() : 0, null);
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005174 if (needed == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005175 return;
5176 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005177
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005178 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005179 }
5180
5181 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5182 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005183 enforceNotIsolatedCaller("grantUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005184 synchronized(this) {
5185 final ProcessRecord r = getRecordForAppLocked(caller);
5186 if (r == null) {
5187 throw new SecurityException("Unable to find app for caller "
5188 + caller
5189 + " when granting permission to uri " + uri);
5190 }
5191 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005192 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 }
5194 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005195 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005196 }
5197
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005198 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005199 null);
5200 }
5201 }
5202
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005203 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005204 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5205 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5206 HashMap<Uri, UriPermission> perms
5207 = mGrantedUriPermissions.get(perm.uid);
5208 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005209 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005210 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005211 perms.remove(perm.uri);
5212 if (perms.size() == 0) {
5213 mGrantedUriPermissions.remove(perm.uid);
5214 }
5215 }
5216 }
5217 }
5218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5220 int modeFlags) {
5221 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5222 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5223 if (modeFlags == 0) {
5224 return;
5225 }
5226
Joe Onorato8a9b2202010-02-26 18:56:32 -08005227 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005228 "Revoking all granted permissions to " + uri);
5229
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005230 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005231
5232 final String authority = uri.getAuthority();
5233 ProviderInfo pi = null;
Amith Yamasani483f3b02012-03-13 16:08:00 -07005234 int userId = UserId.getUserId(callingUid);
5235 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005236 if (cpr != null) {
5237 pi = cpr.info;
5238 } else {
5239 try {
5240 pi = pm.resolveContentProvider(authority,
Amith Yamasani483f3b02012-03-13 16:08:00 -07005241 PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005242 } catch (RemoteException ex) {
5243 }
5244 }
5245 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005246 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005247 return;
5248 }
5249
5250 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07005251 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005252 // Right now, if you are not the original owner of the permission,
5253 // you are not allowed to revoke it.
5254 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5255 throw new SecurityException("Uid " + callingUid
5256 + " does not have permission to uri " + uri);
5257 //}
5258 }
5259
5260 // Go through all of the permissions and remove any that match.
5261 final List<String> SEGMENTS = uri.getPathSegments();
5262 if (SEGMENTS != null) {
5263 final int NS = SEGMENTS.size();
5264 int N = mGrantedUriPermissions.size();
5265 for (int i=0; i<N; i++) {
5266 HashMap<Uri, UriPermission> perms
5267 = mGrantedUriPermissions.valueAt(i);
5268 Iterator<UriPermission> it = perms.values().iterator();
5269 toploop:
5270 while (it.hasNext()) {
5271 UriPermission perm = it.next();
5272 Uri targetUri = perm.uri;
5273 if (!authority.equals(targetUri.getAuthority())) {
5274 continue;
5275 }
5276 List<String> targetSegments = targetUri.getPathSegments();
5277 if (targetSegments == null) {
5278 continue;
5279 }
5280 if (targetSegments.size() < NS) {
5281 continue;
5282 }
5283 for (int j=0; j<NS; j++) {
5284 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5285 continue toploop;
5286 }
5287 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005288 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005289 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005290 perm.clearModes(modeFlags);
5291 if (perm.modeFlags == 0) {
5292 it.remove();
5293 }
5294 }
5295 if (perms.size() == 0) {
5296 mGrantedUriPermissions.remove(
5297 mGrantedUriPermissions.keyAt(i));
5298 N--;
5299 i--;
5300 }
5301 }
5302 }
5303 }
5304
5305 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5306 int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005307 enforceNotIsolatedCaller("revokeUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005308 synchronized(this) {
5309 final ProcessRecord r = getRecordForAppLocked(caller);
5310 if (r == null) {
5311 throw new SecurityException("Unable to find app for caller "
5312 + caller
5313 + " when revoking permission to uri " + uri);
5314 }
5315 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005316 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005317 return;
5318 }
5319
5320 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5321 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5322 if (modeFlags == 0) {
5323 return;
5324 }
5325
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005326 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005327
5328 final String authority = uri.getAuthority();
5329 ProviderInfo pi = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005330 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 if (cpr != null) {
5332 pi = cpr.info;
5333 } else {
5334 try {
5335 pi = pm.resolveContentProvider(authority,
Amith Yamasani483f3b02012-03-13 16:08:00 -07005336 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 } catch (RemoteException ex) {
5338 }
5339 }
5340 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005341 Slog.w(TAG, "No content provider found for permission revoke: "
5342 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005343 return;
5344 }
5345
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005346 revokeUriPermissionLocked(r.uid, uri, modeFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005347 }
5348 }
5349
Dianne Hackborn7e269642010-08-25 19:50:20 -07005350 @Override
5351 public IBinder newUriPermissionOwner(String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005352 enforceNotIsolatedCaller("newUriPermissionOwner");
Dianne Hackborn7e269642010-08-25 19:50:20 -07005353 synchronized(this) {
5354 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5355 return owner.getExternalTokenLocked();
5356 }
5357 }
5358
5359 @Override
5360 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5361 Uri uri, int modeFlags) {
5362 synchronized(this) {
5363 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5364 if (owner == null) {
5365 throw new IllegalArgumentException("Unknown owner: " + token);
5366 }
5367 if (fromUid != Binder.getCallingUid()) {
5368 if (Binder.getCallingUid() != Process.myUid()) {
5369 // Only system code can grant URI permissions on behalf
5370 // of other users.
5371 throw new SecurityException("nice try");
5372 }
5373 }
5374 if (targetPkg == null) {
5375 throw new IllegalArgumentException("null target");
5376 }
5377 if (uri == null) {
5378 throw new IllegalArgumentException("null uri");
5379 }
5380
5381 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5382 }
5383 }
5384
5385 @Override
5386 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5387 synchronized(this) {
5388 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5389 if (owner == null) {
5390 throw new IllegalArgumentException("Unknown owner: " + token);
5391 }
5392
5393 if (uri == null) {
5394 owner.removeUriPermissionsLocked(mode);
5395 } else {
5396 owner.removeUriPermissionLocked(uri, mode);
5397 }
5398 }
5399 }
5400
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005401 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5402 synchronized (this) {
5403 ProcessRecord app =
5404 who != null ? getRecordForAppLocked(who) : null;
5405 if (app == null) return;
5406
5407 Message msg = Message.obtain();
5408 msg.what = WAIT_FOR_DEBUGGER_MSG;
5409 msg.obj = app;
5410 msg.arg1 = waiting ? 1 : 0;
5411 mHandler.sendMessage(msg);
5412 }
5413 }
5414
5415 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005416 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5417 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005418 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn59325eb2012-05-09 18:45:20 -07005419 outInfo.totalMem = Process.getTotalMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005420 outInfo.threshold = homeAppMem;
5421 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5422 outInfo.hiddenAppThreshold = hiddenAppMem;
5423 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005424 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005425 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5426 ProcessList.VISIBLE_APP_ADJ);
5427 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5428 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005429 }
5430
5431 // =========================================================
5432 // TASK MANAGEMENT
5433 // =========================================================
5434
5435 public List getTasks(int maxNum, int flags,
5436 IThumbnailReceiver receiver) {
5437 ArrayList list = new ArrayList();
5438
5439 PendingThumbnailsRecord pending = null;
5440 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005441 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005442
5443 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005444 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005445 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5446 + ", receiver=" + receiver);
5447
5448 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5449 != PackageManager.PERMISSION_GRANTED) {
5450 if (receiver != null) {
5451 // If the caller wants to wait for pending thumbnails,
5452 // it ain't gonna get them.
5453 try {
5454 receiver.finished();
5455 } catch (RemoteException ex) {
5456 }
5457 }
5458 String msg = "Permission Denial: getTasks() from pid="
5459 + Binder.getCallingPid()
5460 + ", uid=" + Binder.getCallingUid()
5461 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005462 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005463 throw new SecurityException(msg);
5464 }
5465
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005466 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005467 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005468 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005469 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005470 TaskRecord curTask = null;
5471 int numActivities = 0;
5472 int numRunning = 0;
5473 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005474 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005475 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005476 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477
5478 // Initialize state for next task if needed.
5479 if (top == null ||
5480 (top.state == ActivityState.INITIALIZING
5481 && top.task == r.task)) {
5482 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005483 curTask = r.task;
5484 numActivities = numRunning = 0;
5485 }
5486
5487 // Add 'r' into the current task.
5488 numActivities++;
5489 if (r.app != null && r.app.thread != null) {
5490 numRunning++;
5491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005492
Joe Onorato8a9b2202010-02-26 18:56:32 -08005493 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005494 TAG, r.intent.getComponent().flattenToShortString()
5495 + ": task=" + r.task);
5496
5497 // If the next one is a different task, generate a new
5498 // TaskInfo entry for what we have.
5499 if (next == null || next.task != curTask) {
5500 ActivityManager.RunningTaskInfo ci
5501 = new ActivityManager.RunningTaskInfo();
5502 ci.id = curTask.taskId;
5503 ci.baseActivity = r.intent.getComponent();
5504 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005505 if (top.thumbHolder != null) {
5506 ci.description = top.thumbHolder.lastDescription;
5507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005508 ci.numActivities = numActivities;
5509 ci.numRunning = numRunning;
5510 //System.out.println(
5511 // "#" + maxNum + ": " + " descr=" + ci.description);
5512 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005513 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005514 TAG, "State=" + top.state + "Idle=" + top.idle
5515 + " app=" + top.app
5516 + " thr=" + (top.app != null ? top.app.thread : null));
5517 if (top.state == ActivityState.RESUMED
5518 || top.state == ActivityState.PAUSING) {
5519 if (top.idle && top.app != null
5520 && top.app.thread != null) {
5521 topRecord = top;
5522 topThumbnail = top.app.thread;
5523 } else {
5524 top.thumbnailNeeded = true;
5525 }
5526 }
5527 if (pending == null) {
5528 pending = new PendingThumbnailsRecord(receiver);
5529 }
5530 pending.pendingRecords.add(top);
5531 }
5532 list.add(ci);
5533 maxNum--;
5534 top = null;
5535 }
5536 }
5537
5538 if (pending != null) {
5539 mPendingThumbnails.add(pending);
5540 }
5541 }
5542
Joe Onorato8a9b2202010-02-26 18:56:32 -08005543 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005544
5545 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005546 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005547 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005548 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005549 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005550 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005551 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005552 }
5553 }
5554
5555 if (pending == null && receiver != null) {
5556 // In this case all thumbnails were available and the client
5557 // is being asked to be told when the remaining ones come in...
5558 // which is unusually, since the top-most currently running
5559 // activity should never have a canned thumbnail! Oh well.
5560 try {
5561 receiver.finished();
5562 } catch (RemoteException ex) {
5563 }
5564 }
5565
5566 return list;
5567 }
5568
5569 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
5570 int flags) {
Amith Yamasani742a6712011-05-04 14:49:28 -07005571 final int callingUid = Binder.getCallingUid();
5572 // If it's the system uid asking, then use the current user id.
5573 // TODO: Make sure that there aren't any other legitimate calls from the system uid that
5574 // require the entire list.
5575 final int callingUserId = callingUid == Process.SYSTEM_UID
5576 ? mCurrentUserId : UserId.getUserId(callingUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005577 synchronized (this) {
5578 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5579 "getRecentTasks()");
Dianne Hackborn8238e712012-04-24 11:15:40 -07005580 final boolean detailed = checkCallingPermission(
5581 android.Manifest.permission.GET_DETAILED_TASKS)
5582 == PackageManager.PERMISSION_GRANTED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005583
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005584 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005586 final int N = mRecentTasks.size();
5587 ArrayList<ActivityManager.RecentTaskInfo> res
5588 = new ArrayList<ActivityManager.RecentTaskInfo>(
5589 maxNum < N ? maxNum : N);
5590 for (int i=0; i<N && maxNum > 0; i++) {
5591 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07005592 // Only add calling user's recent tasks
5593 if (tr.userId != callingUserId) continue;
Dianne Hackborn905577f2011-09-07 18:31:28 -07005594 // Return the entry if desired by the caller. We always return
5595 // the first entry, because callers always expect this to be the
Amith Yamasani742a6712011-05-04 14:49:28 -07005596 // foreground app. We may filter others if the caller has
Dianne Hackborn905577f2011-09-07 18:31:28 -07005597 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5598 // we should exclude the entry.
Amith Yamasani742a6712011-05-04 14:49:28 -07005599
Dianne Hackborn905577f2011-09-07 18:31:28 -07005600 if (i == 0
5601 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005602 || (tr.intent == null)
5603 || ((tr.intent.getFlags()
5604 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5605 ActivityManager.RecentTaskInfo rti
5606 = new ActivityManager.RecentTaskInfo();
5607 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005608 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005609 rti.baseIntent = new Intent(
5610 tr.intent != null ? tr.intent : tr.affinityIntent);
Dianne Hackborn8238e712012-04-24 11:15:40 -07005611 if (!detailed) {
5612 rti.baseIntent.replaceExtras((Bundle)null);
5613 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005614 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005615 rti.description = tr.lastDescription;
5616
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005617 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5618 // Check whether this activity is currently available.
5619 try {
5620 if (rti.origActivity != null) {
Amith Yamasani483f3b02012-03-13 16:08:00 -07005621 if (pm.getActivityInfo(rti.origActivity, 0, callingUserId)
5622 == null) {
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005623 continue;
5624 }
5625 } else if (rti.baseIntent != null) {
5626 if (pm.queryIntentActivities(rti.baseIntent,
Amith Yamasani483f3b02012-03-13 16:08:00 -07005627 null, 0, callingUserId) == null) {
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005628 continue;
5629 }
5630 }
5631 } catch (RemoteException e) {
5632 // Will never happen.
5633 }
5634 }
5635
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005636 res.add(rti);
5637 maxNum--;
5638 }
5639 }
5640 return res;
5641 }
5642 }
5643
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005644 private TaskRecord taskForIdLocked(int id) {
5645 final int N = mRecentTasks.size();
5646 for (int i=0; i<N; i++) {
5647 TaskRecord tr = mRecentTasks.get(i);
5648 if (tr.taskId == id) {
5649 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005650 }
5651 }
5652 return null;
5653 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005654
5655 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5656 synchronized (this) {
5657 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5658 "getTaskThumbnails()");
5659 TaskRecord tr = taskForIdLocked(id);
5660 if (tr != null) {
5661 return mMainStack.getTaskThumbnailsLocked(tr);
5662 }
5663 }
5664 return null;
5665 }
5666
5667 public boolean removeSubTask(int taskId, int subTaskIndex) {
5668 synchronized (this) {
5669 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5670 "removeSubTask()");
5671 long ident = Binder.clearCallingIdentity();
5672 try {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005673 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5674 true) != null;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005675 } finally {
5676 Binder.restoreCallingIdentity(ident);
5677 }
5678 }
5679 }
5680
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005681 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5682 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005683 Intent baseIntent = new Intent(
5684 tr.intent != null ? tr.intent : tr.affinityIntent);
5685 ComponentName component = baseIntent.getComponent();
5686 if (component == null) {
5687 Slog.w(TAG, "Now component for base intent of task: " + tr);
5688 return;
5689 }
5690
5691 // Find any running services associated with this app.
5692 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005693 for (ServiceRecord sr : mServiceMap.getAllServices(tr.userId)) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005694 if (sr.packageName.equals(component.getPackageName())) {
5695 services.add(sr);
5696 }
5697 }
5698
5699 // Take care of any running services associated with the app.
5700 for (int i=0; i<services.size(); i++) {
5701 ServiceRecord sr = services.get(i);
5702 if (sr.startRequested) {
5703 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005704 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005705 stopServiceLocked(sr);
5706 } else {
5707 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005708 sr.makeNextStartId(), baseIntent, null));
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005709 if (sr.app != null && sr.app.thread != null) {
5710 sendServiceArgsLocked(sr, false);
5711 }
5712 }
5713 }
5714 }
5715
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005716 if (killProcesses) {
5717 // Find any running processes associated with this app.
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005718 final String pkg = component.getPackageName();
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005719 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005720 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5721 for (SparseArray<ProcessRecord> uids : pmap.values()) {
5722 for (int i=0; i<uids.size(); i++) {
5723 ProcessRecord proc = uids.valueAt(i);
5724 if (proc.userId != tr.userId) {
5725 continue;
5726 }
5727 if (!proc.pkgList.contains(pkg)) {
5728 continue;
5729 }
5730 procs.add(proc);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005731 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005732 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005733
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005734 // Kill the running processes.
5735 for (int i=0; i<procs.size(); i++) {
5736 ProcessRecord pr = procs.get(i);
5737 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5738 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5739 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5740 pr.processName, pr.setAdj, "remove task");
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005741 pr.killedBackground = true;
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005742 Process.killProcessQuiet(pr.pid);
5743 } else {
5744 pr.waitingToKill = "remove task";
5745 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005746 }
5747 }
5748 }
5749
5750 public boolean removeTask(int taskId, int flags) {
5751 synchronized (this) {
5752 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5753 "removeTask()");
5754 long ident = Binder.clearCallingIdentity();
5755 try {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005756 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5757 false);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005758 if (r != null) {
5759 mRecentTasks.remove(r.task);
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005760 cleanUpRemovedTaskLocked(r.task, flags);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005761 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005762 } else {
5763 TaskRecord tr = null;
5764 int i=0;
5765 while (i < mRecentTasks.size()) {
5766 TaskRecord t = mRecentTasks.get(i);
5767 if (t.taskId == taskId) {
5768 tr = t;
5769 break;
5770 }
5771 i++;
5772 }
5773 if (tr != null) {
5774 if (tr.numActivities <= 0) {
5775 // Caller is just removing a recent task that is
5776 // not actively running. That is easy!
5777 mRecentTasks.remove(i);
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005778 cleanUpRemovedTaskLocked(tr, flags);
5779 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005780 } else {
5781 Slog.w(TAG, "removeTask: task " + taskId
5782 + " does not have activities to remove, "
5783 + " but numActivities=" + tr.numActivities
5784 + ": " + tr);
5785 }
5786 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005787 }
5788 } finally {
5789 Binder.restoreCallingIdentity(ident);
5790 }
5791 }
5792 return false;
5793 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005795 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5796 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005797 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005798 TaskRecord jt = startTask;
5799
5800 // First look backwards
5801 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005802 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005803 if (r.task != jt) {
5804 jt = r.task;
5805 if (affinity.equals(jt.affinity)) {
5806 return j;
5807 }
5808 }
5809 }
5810
5811 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005812 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005813 jt = startTask;
5814 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005815 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005816 if (r.task != jt) {
5817 if (affinity.equals(jt.affinity)) {
5818 return j;
5819 }
5820 jt = r.task;
5821 }
5822 }
5823
5824 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005825 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005826 return N-1;
5827 }
5828
5829 return -1;
5830 }
5831
5832 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005833 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005834 */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005835 public void moveTaskToFront(int task, int flags, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005836 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5837 "moveTaskToFront()");
5838
5839 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005840 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5841 Binder.getCallingUid(), "Task to front")) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005842 ActivityOptions.abort(options);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005843 return;
5844 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005845 final long origId = Binder.clearCallingIdentity();
5846 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005847 TaskRecord tr = taskForIdLocked(task);
5848 if (tr != null) {
5849 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5850 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005851 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005852 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5853 // Caller wants the home activity moved with it. To accomplish this,
5854 // we'll just move the home task to the top first.
5855 mMainStack.moveHomeToFrontLocked();
5856 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005857 mMainStack.moveTaskToFrontLocked(tr, null, options);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005858 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005859 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005860 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5861 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005862 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005863 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5864 mMainStack.mUserLeaving = true;
5865 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005866 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5867 // Caller wants the home activity moved with it. To accomplish this,
5868 // we'll just move the home task to the top first.
5869 mMainStack.moveHomeToFrontLocked();
5870 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005871 mMainStack.moveTaskToFrontLocked(hr.task, null, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005872 return;
5873 }
5874 }
5875 } finally {
5876 Binder.restoreCallingIdentity(origId);
5877 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005878 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005879 }
5880 }
5881
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005882 public void moveTaskToBack(int task) {
5883 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5884 "moveTaskToBack()");
5885
5886 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005887 if (mMainStack.mResumedActivity != null
5888 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005889 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5890 Binder.getCallingUid(), "Task to back")) {
5891 return;
5892 }
5893 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005894 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005895 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005896 Binder.restoreCallingIdentity(origId);
5897 }
5898 }
5899
5900 /**
5901 * Moves an activity, and all of the other activities within the same task, to the bottom
5902 * of the history stack. The activity's order within the task is unchanged.
5903 *
5904 * @param token A reference to the activity we wish to move
5905 * @param nonRoot If false then this only works if the activity is the root
5906 * of a task; if true it will work for any activity in a task.
5907 * @return Returns true if the move completed, false if not.
5908 */
5909 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005910 enforceNotIsolatedCaller("moveActivityTaskToBack");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005911 synchronized(this) {
5912 final long origId = Binder.clearCallingIdentity();
5913 int taskId = getTaskForActivityLocked(token, !nonRoot);
5914 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005915 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005916 }
5917 Binder.restoreCallingIdentity(origId);
5918 }
5919 return false;
5920 }
5921
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005922 public void moveTaskBackwards(int task) {
5923 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5924 "moveTaskBackwards()");
5925
5926 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005927 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5928 Binder.getCallingUid(), "Task backwards")) {
5929 return;
5930 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005931 final long origId = Binder.clearCallingIdentity();
5932 moveTaskBackwardsLocked(task);
5933 Binder.restoreCallingIdentity(origId);
5934 }
5935 }
5936
5937 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005938 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005939 }
5940
5941 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5942 synchronized(this) {
5943 return getTaskForActivityLocked(token, onlyRoot);
5944 }
5945 }
5946
5947 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005948 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005949 TaskRecord lastTask = null;
5950 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005951 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005952 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005953 if (!onlyRoot || lastTask != r.task) {
5954 return r.task.taskId;
5955 }
5956 return -1;
5957 }
5958 lastTask = r.task;
5959 }
5960
5961 return -1;
5962 }
5963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005964 // =========================================================
5965 // THUMBNAILS
5966 // =========================================================
5967
5968 public void reportThumbnail(IBinder token,
5969 Bitmap thumbnail, CharSequence description) {
5970 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5971 final long origId = Binder.clearCallingIdentity();
5972 sendPendingThumbnail(null, token, thumbnail, description, true);
5973 Binder.restoreCallingIdentity(origId);
5974 }
5975
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005976 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005977 Bitmap thumbnail, CharSequence description, boolean always) {
5978 TaskRecord task = null;
5979 ArrayList receivers = null;
5980
5981 //System.out.println("Send pending thumbnail: " + r);
5982
5983 synchronized(this) {
5984 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005985 r = mMainStack.isInStackLocked(token);
5986 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005987 return;
5988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005989 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005990 if (thumbnail == null && r.thumbHolder != null) {
5991 thumbnail = r.thumbHolder.lastThumbnail;
5992 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005993 }
5994 if (thumbnail == null && !always) {
5995 // If there is no thumbnail, and this entry is not actually
5996 // going away, then abort for now and pick up the next
5997 // thumbnail we get.
5998 return;
5999 }
6000 task = r.task;
6001
6002 int N = mPendingThumbnails.size();
6003 int i=0;
6004 while (i<N) {
6005 PendingThumbnailsRecord pr =
6006 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6007 //System.out.println("Looking in " + pr.pendingRecords);
6008 if (pr.pendingRecords.remove(r)) {
6009 if (receivers == null) {
6010 receivers = new ArrayList();
6011 }
6012 receivers.add(pr);
6013 if (pr.pendingRecords.size() == 0) {
6014 pr.finished = true;
6015 mPendingThumbnails.remove(i);
6016 N--;
6017 continue;
6018 }
6019 }
6020 i++;
6021 }
6022 }
6023
6024 if (receivers != null) {
6025 final int N = receivers.size();
6026 for (int i=0; i<N; i++) {
6027 try {
6028 PendingThumbnailsRecord pr =
6029 (PendingThumbnailsRecord)receivers.get(i);
6030 pr.receiver.newThumbnail(
6031 task != null ? task.taskId : -1, thumbnail, description);
6032 if (pr.finished) {
6033 pr.receiver.finished();
6034 }
6035 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006036 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006037 }
6038 }
6039 }
6040 }
6041
6042 // =========================================================
6043 // CONTENT PROVIDERS
6044 // =========================================================
6045
Jeff Brown10e89712011-07-08 18:52:57 -07006046 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6047 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006048 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006049 providers = AppGlobals.getPackageManager().
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006050 queryContentProviders(app.processName, app.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006051 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 } catch (RemoteException ex) {
6053 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006054 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006055 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6056 int userId = app.userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006057 if (providers != null) {
6058 final int N = providers.size();
6059 for (int i=0; i<N; i++) {
6060 ProviderInfo cpi =
6061 (ProviderInfo)providers.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07006062
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006063 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006064 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006065 if (cpr == null) {
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006066 cpr = new ContentProviderRecord(this, cpi, app.info, comp);
Amith Yamasani742a6712011-05-04 14:49:28 -07006067 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006068 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006069 if (DEBUG_MU)
6070 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006071 app.pubProviders.put(cpi.name, cpr);
6072 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07006073 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006074 }
6075 }
6076 return providers;
6077 }
6078
Jeff Sharkey110a6b62012-03-12 11:12:41 -07006079 /**
6080 * Check if {@link ProcessRecord} has a possible chance at accessing the
6081 * given {@link ProviderInfo}. Final permission checking is always done
6082 * in {@link ContentProvider}.
6083 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006084 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07006085 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006087 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006089 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006090 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006091 return null;
6092 }
6093 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006094 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006095 == PackageManager.PERMISSION_GRANTED) {
6096 return null;
6097 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006098
6099 PathPermission[] pps = cpi.pathPermissions;
6100 if (pps != null) {
6101 int i = pps.length;
6102 while (i > 0) {
6103 i--;
6104 PathPermission pp = pps[i];
6105 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006106 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006107 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006108 return null;
6109 }
6110 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006111 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006112 == PackageManager.PERMISSION_GRANTED) {
6113 return null;
6114 }
6115 }
6116 }
6117
Dianne Hackbornb424b632010-08-18 15:59:05 -07006118 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6119 if (perms != null) {
6120 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6121 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6122 return null;
6123 }
6124 }
6125 }
6126
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006127 String msg;
6128 if (!cpi.exported) {
6129 msg = "Permission Denial: opening provider " + cpi.name
6130 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6131 + ", uid=" + callingUid + ") that is not exported from uid "
6132 + cpi.applicationInfo.uid;
6133 } else {
6134 msg = "Permission Denial: opening provider " + cpi.name
6135 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6136 + ", uid=" + callingUid + ") requires "
6137 + cpi.readPermission + " or " + cpi.writePermission;
6138 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006139 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 return msg;
6141 }
6142
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006143 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6144 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006145 if (r != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006146 for (int i=0; i<r.conProviders.size(); i++) {
6147 ContentProviderConnection conn = r.conProviders.get(i);
6148 if (conn.provider == cpr) {
6149 if (DEBUG_PROVIDER) Slog.v(TAG,
6150 "Adding provider requested by "
6151 + r.processName + " from process "
6152 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6153 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6154 if (stable) {
6155 conn.stableCount++;
6156 conn.numStableIncs++;
6157 } else {
6158 conn.unstableCount++;
6159 conn.numUnstableIncs++;
6160 }
6161 return conn;
6162 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006163 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006164 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6165 if (stable) {
6166 conn.stableCount = 1;
6167 conn.numStableIncs = 1;
6168 } else {
6169 conn.unstableCount = 1;
6170 conn.numUnstableIncs = 1;
6171 }
6172 cpr.connections.add(conn);
6173 r.conProviders.add(conn);
6174 return conn;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006175 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006176 cpr.addExternalProcessHandleLocked(externalProcessToken);
6177 return null;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006178 }
6179
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006180 boolean decProviderCountLocked(ContentProviderConnection conn,
6181 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6182 if (conn != null) {
6183 cpr = conn.provider;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006184 if (DEBUG_PROVIDER) Slog.v(TAG,
6185 "Removing provider requested by "
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006186 + conn.client.processName + " from process "
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006187 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006188 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6189 if (stable) {
6190 conn.stableCount--;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006191 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006192 conn.unstableCount--;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006193 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006194 if (conn.stableCount == 0 && conn.unstableCount == 0) {
6195 cpr.connections.remove(conn);
6196 conn.client.conProviders.remove(conn);
6197 return true;
6198 }
6199 return false;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006200 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006201 cpr.removeExternalProcessHandleLocked(externalProcessToken);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006202 return false;
6203 }
6204
Amith Yamasani742a6712011-05-04 14:49:28 -07006205 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006206 String name, IBinder token, boolean stable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006207 ContentProviderRecord cpr;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006208 ContentProviderConnection conn = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006209 ProviderInfo cpi = null;
6210
6211 synchronized(this) {
6212 ProcessRecord r = null;
6213 if (caller != null) {
6214 r = getRecordForAppLocked(caller);
6215 if (r == null) {
6216 throw new SecurityException(
6217 "Unable to find app for caller " + caller
6218 + " (pid=" + Binder.getCallingPid()
6219 + ") when getting content provider " + name);
6220 }
6221 }
6222
6223 // First check if this content provider has been published...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006224 int userId = UserId.getUserId(r != null ? r.uid : Binder.getCallingUid());
Amith Yamasani742a6712011-05-04 14:49:28 -07006225 cpr = mProviderMap.getProviderByName(name, userId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006226 boolean providerRunning = cpr != null;
6227 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006228 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07006229 String msg;
6230 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6231 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006232 }
6233
6234 if (r != null && cpr.canRunHere(r)) {
6235 // This provider has been published or is in the process
6236 // of being published... but it is also allowed to run
6237 // in the caller's process, so don't make a connection
6238 // and just let the caller instantiate its own instance.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006239 ContentProviderHolder holder = cpr.newHolder(null);
6240 // don't give caller the provider object, it needs
6241 // to make its own.
6242 holder.provider = null;
6243 return holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006244 }
6245
6246 final long origId = Binder.clearCallingIdentity();
6247
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006248 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 // return it right away.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006250 conn = incProviderCountLocked(r, cpr, token, stable);
6251 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006252 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006253 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07006254 // make sure to count it as being accessed and thus
6255 // back up on the LRU list. This is good because
6256 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006257 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07006258 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07006259 }
6260
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006261 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006262 if (false) {
6263 if (cpr.name.flattenToShortString().equals(
6264 "com.android.providers.calendar/.CalendarProvider2")) {
6265 Slog.v(TAG, "****************** KILLING "
6266 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006267 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006268 }
6269 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006270 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006271 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6272 // NOTE: there is still a race here where a signal could be
6273 // pending on the process even though we managed to update its
6274 // adj level. Not sure what to do about this, but at least
6275 // the race is now smaller.
6276 if (!success) {
6277 // Uh oh... it looks like the provider's process
6278 // has been killed on us. We need to wait for a new
6279 // process to be started, and make sure its death
6280 // doesn't kill our process.
6281 Slog.i(TAG,
6282 "Existing provider " + cpr.name.flattenToShortString()
6283 + " is crashing; detaching " + r);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006284 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006285 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006286 if (!lastRef) {
6287 // This wasn't the last ref our process had on
6288 // the provider... we have now been killed, bail.
6289 return null;
6290 }
6291 providerRunning = false;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006292 conn = null;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006293 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006294 }
6295
6296 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006298
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006299 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006300 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006301 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006302 resolveContentProvider(name,
Amith Yamasani483f3b02012-03-13 16:08:00 -07006303 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006304 } catch (RemoteException ex) {
6305 }
6306 if (cpi == null) {
6307 return null;
6308 }
Amith Yamasania4a54e22012-04-16 15:44:19 -07006309 if (isSingleton(cpi.processName, cpi.applicationInfo)) {
6310 userId = 0;
6311 }
Amith Yamasani483f3b02012-03-13 16:08:00 -07006312 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07006313
Dianne Hackbornb424b632010-08-18 15:59:05 -07006314 String msg;
6315 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6316 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006317 }
6318
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006319 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006320 && !cpi.processName.equals("system")) {
6321 // If this content provider does not run in the system
6322 // process, and the system is not yet ready to run other
6323 // processes, then fail fast instead of hanging.
6324 throw new IllegalArgumentException(
6325 "Attempt to launch content provider before system ready");
6326 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006327
6328 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani483f3b02012-03-13 16:08:00 -07006329 cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006330 final boolean firstClass = cpr == null;
6331 if (firstClass) {
6332 try {
6333 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006334 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006335 getApplicationInfo(
6336 cpi.applicationInfo.packageName,
Amith Yamasani483f3b02012-03-13 16:08:00 -07006337 STOCK_PM_FLAGS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006338 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006339 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006340 + cpi.name);
6341 return null;
6342 }
Amith Yamasani483f3b02012-03-13 16:08:00 -07006343 ai = getAppInfoForUser(ai, userId);
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006344 cpr = new ContentProviderRecord(this, cpi, ai, comp);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006345 } catch (RemoteException ex) {
6346 // pm is in same process, this will never happen.
6347 }
6348 }
6349
6350 if (r != null && cpr.canRunHere(r)) {
6351 // If this is a multiprocess provider, then just return its
6352 // info and allow the caller to instantiate it. Only do
6353 // this if the provider is the same user as the caller's
6354 // process, or can run as root (so can be in any process).
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006355 return cpr.newHolder(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006356 }
6357
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006358 if (DEBUG_PROVIDER) {
6359 RuntimeException e = new RuntimeException("here");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006360 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006361 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006362 }
6363
6364 // This is single process, and our app is now connecting to it.
6365 // See if we are already in the process of launching this
6366 // provider.
6367 final int N = mLaunchingProviders.size();
6368 int i;
6369 for (i=0; i<N; i++) {
6370 if (mLaunchingProviders.get(i) == cpr) {
6371 break;
6372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006373 }
6374
6375 // If the provider is not already being launched, then get it
6376 // started.
6377 if (i >= N) {
6378 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006379
6380 try {
6381 // Content provider is now in use, its package can't be stopped.
6382 try {
6383 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -07006384 cpr.appInfo.packageName, false, userId);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006385 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006386 } catch (IllegalArgumentException e) {
6387 Slog.w(TAG, "Failed trying to unstop package "
6388 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006389 }
6390
6391 ProcessRecord proc = startProcessLocked(cpi.processName,
6392 cpr.appInfo, false, 0, "content provider",
6393 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006394 cpi.name), false, false);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006395 if (proc == null) {
6396 Slog.w(TAG, "Unable to launch app "
6397 + cpi.applicationInfo.packageName + "/"
6398 + cpi.applicationInfo.uid + " for provider "
6399 + name + ": process is bad");
6400 return null;
6401 }
6402 cpr.launchingApp = proc;
6403 mLaunchingProviders.add(cpr);
6404 } finally {
6405 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 }
6408
6409 // Make sure the provider is published (the same provider class
6410 // may be published under multiple names).
6411 if (firstClass) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006412 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006413 }
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006414
Amith Yamasani742a6712011-05-04 14:49:28 -07006415 mProviderMap.putProviderByName(name, cpr);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006416 conn = incProviderCountLocked(r, cpr, token, stable);
6417 if (conn != null) {
6418 conn.waiting = true;
6419 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006420 }
6421 }
6422
6423 // Wait for the provider to be published...
6424 synchronized (cpr) {
6425 while (cpr.provider == null) {
6426 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006427 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006428 + cpi.applicationInfo.packageName + "/"
6429 + cpi.applicationInfo.uid + " for provider "
6430 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006431 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006432 cpi.applicationInfo.packageName,
6433 cpi.applicationInfo.uid, name);
6434 return null;
6435 }
6436 try {
Amith Yamasani742a6712011-05-04 14:49:28 -07006437 if (DEBUG_MU) {
6438 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6439 + cpr.launchingApp);
6440 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006441 if (conn != null) {
6442 conn.waiting = true;
6443 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006444 cpr.wait();
6445 } catch (InterruptedException ex) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006446 } finally {
6447 if (conn != null) {
6448 conn.waiting = false;
6449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006450 }
6451 }
6452 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006453 return cpr != null ? cpr.newHolder(conn) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 }
6455
6456 public final ContentProviderHolder getContentProvider(
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006457 IApplicationThread caller, String name, boolean stable) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006458 enforceNotIsolatedCaller("getContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006459 if (caller == null) {
6460 String msg = "null IApplicationThread when getting content provider "
6461 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006462 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006463 throw new SecurityException(msg);
6464 }
6465
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006466 return getContentProviderImpl(caller, name, null, stable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006467 }
6468
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006469 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6470 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6471 "Do not have permission in call getContentProviderExternal()");
6472 return getContentProviderExternalUnchecked(name, token);
6473 }
6474
6475 private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006476 return getContentProviderImpl(null, name, token, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006477 }
6478
6479 /**
6480 * Drop a content provider from a ProcessRecord's bookkeeping
6481 * @param cpr
6482 */
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006483 public void removeContentProvider(IBinder connection, boolean stable) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006484 enforceNotIsolatedCaller("removeContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006485 synchronized (this) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006486 ContentProviderConnection conn;
6487 try {
6488 conn = (ContentProviderConnection)connection;
6489 } catch (ClassCastException e) {
6490 String msg ="removeContentProvider: " + connection
6491 + " not a ContentProviderConnection";
6492 Slog.w(TAG, msg);
6493 throw new IllegalArgumentException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006494 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006495 if (conn == null) {
6496 throw new NullPointerException("connection is null");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006498 if (decProviderCountLocked(conn, null, null, stable)) {
6499 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006500 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006501 }
6502 }
6503
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006504 public void removeContentProviderExternal(String name, IBinder token) {
6505 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6506 "Do not have permission in call removeContentProviderExternal()");
6507 removeContentProviderExternalUnchecked(name, token);
6508 }
6509
6510 private void removeContentProviderExternalUnchecked(String name, IBinder token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006511 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006512 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
6513 Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006514 if(cpr == null) {
6515 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006516 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006517 return;
6518 }
6519
6520 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006521 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006522 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
6523 Binder.getOrigCallingUser());
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006524 if (localCpr.hasExternalProcessHandles()) {
6525 if (localCpr.removeExternalProcessHandleLocked(token)) {
6526 updateOomAdjLocked();
6527 } else {
6528 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6529 + " with no external reference for token: "
6530 + token + ".");
6531 }
6532 } else {
6533 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6534 + " with no external references.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006536 }
6537 }
6538
6539 public final void publishContentProviders(IApplicationThread caller,
6540 List<ContentProviderHolder> providers) {
6541 if (providers == null) {
6542 return;
6543 }
6544
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006545 enforceNotIsolatedCaller("publishContentProviders");
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006546 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006547 final ProcessRecord r = getRecordForAppLocked(caller);
Amith Yamasani742a6712011-05-04 14:49:28 -07006548 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006549 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006550 if (r == null) {
6551 throw new SecurityException(
6552 "Unable to find app for caller " + caller
6553 + " (pid=" + Binder.getCallingPid()
6554 + ") when publishing content providers");
6555 }
6556
6557 final long origId = Binder.clearCallingIdentity();
6558
6559 final int N = providers.size();
6560 for (int i=0; i<N; i++) {
6561 ContentProviderHolder src = providers.get(i);
6562 if (src == null || src.info == null || src.provider == null) {
6563 continue;
6564 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006565 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006566 if (DEBUG_MU)
6567 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006568 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006569 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006570 mProviderMap.putProviderByClass(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006571 String names[] = dst.info.authority.split(";");
6572 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006573 mProviderMap.putProviderByName(names[j], dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006574 }
6575
6576 int NL = mLaunchingProviders.size();
6577 int j;
6578 for (j=0; j<NL; j++) {
6579 if (mLaunchingProviders.get(j) == dst) {
6580 mLaunchingProviders.remove(j);
6581 j--;
6582 NL--;
6583 }
6584 }
6585 synchronized (dst) {
6586 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006587 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006588 dst.notifyAll();
6589 }
6590 updateOomAdjLocked(r);
6591 }
6592 }
6593
6594 Binder.restoreCallingIdentity(origId);
6595 }
6596 }
6597
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006598 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6599 ContentProviderConnection conn;
6600 try {
6601 conn = (ContentProviderConnection)connection;
6602 } catch (ClassCastException e) {
6603 String msg ="refContentProvider: " + connection
6604 + " not a ContentProviderConnection";
6605 Slog.w(TAG, msg);
6606 throw new IllegalArgumentException(msg);
6607 }
6608 if (conn == null) {
6609 throw new NullPointerException("connection is null");
6610 }
6611
6612 synchronized (this) {
6613 if (stable > 0) {
6614 conn.numStableIncs += stable;
6615 }
6616 stable = conn.stableCount + stable;
6617 if (stable < 0) {
6618 throw new IllegalStateException("stableCount < 0: " + stable);
6619 }
6620
6621 if (unstable > 0) {
6622 conn.numUnstableIncs += unstable;
6623 }
6624 unstable = conn.unstableCount + unstable;
6625 if (unstable < 0) {
6626 throw new IllegalStateException("unstableCount < 0: " + unstable);
6627 }
6628
6629 if ((stable+unstable) <= 0) {
6630 throw new IllegalStateException("ref counts can't go to zero here: stable="
6631 + stable + " unstable=" + unstable);
6632 }
6633 conn.stableCount = stable;
6634 conn.unstableCount = unstable;
6635 return !conn.dead;
6636 }
6637 }
6638
6639 public void unstableProviderDied(IBinder connection) {
6640 ContentProviderConnection conn;
6641 try {
6642 conn = (ContentProviderConnection)connection;
6643 } catch (ClassCastException e) {
6644 String msg ="refContentProvider: " + connection
6645 + " not a ContentProviderConnection";
6646 Slog.w(TAG, msg);
6647 throw new IllegalArgumentException(msg);
6648 }
6649 if (conn == null) {
6650 throw new NullPointerException("connection is null");
6651 }
6652
6653 // Safely retrieve the content provider associated with the connection.
6654 IContentProvider provider;
6655 synchronized (this) {
6656 provider = conn.provider.provider;
6657 }
6658
6659 if (provider == null) {
6660 // Um, yeah, we're way ahead of you.
6661 return;
6662 }
6663
6664 // Make sure the caller is being honest with us.
6665 if (provider.asBinder().pingBinder()) {
6666 // Er, no, still looks good to us.
6667 synchronized (this) {
6668 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6669 + " says " + conn + " died, but we don't agree");
6670 return;
6671 }
6672 }
6673
6674 // Well look at that! It's dead!
6675 synchronized (this) {
6676 if (conn.provider.provider != provider) {
6677 // But something changed... good enough.
6678 return;
6679 }
6680
6681 ProcessRecord proc = conn.provider.proc;
6682 if (proc == null || proc.thread == null) {
6683 // Seems like the process is already cleaned up.
6684 return;
6685 }
6686
6687 // As far as we're concerned, this is just like receiving a
6688 // death notification... just a bit prematurely.
6689 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6690 + ") early provider death");
Dianne Hackbornbd145db2012-06-05 16:20:46 -07006691 final long ident = Binder.clearCallingIdentity();
6692 try {
6693 appDiedLocked(proc, proc.pid, proc.thread);
6694 } finally {
6695 Binder.restoreCallingIdentity(ident);
6696 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006697 }
6698 }
6699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006700 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006701 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006702 synchronized (mSelf) {
6703 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6704 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006705 if (providers != null) {
6706 for (int i=providers.size()-1; i>=0; i--) {
6707 ProviderInfo pi = (ProviderInfo)providers.get(i);
6708 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6709 Slog.w(TAG, "Not installing system proc provider " + pi.name
6710 + ": not system .apk");
6711 providers.remove(i);
6712 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006713 }
6714 }
6715 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006716 if (providers != null) {
6717 mSystemThread.installSystemProviders(providers);
6718 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006719
6720 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006721
6722 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006723 }
6724
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006725 /**
6726 * Allows app to retrieve the MIME type of a URI without having permission
6727 * to access its content provider.
6728 *
6729 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6730 *
6731 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6732 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6733 */
6734 public String getProviderMimeType(Uri uri) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006735 enforceNotIsolatedCaller("getProviderMimeType");
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006736 final String name = uri.getAuthority();
6737 final long ident = Binder.clearCallingIdentity();
6738 ContentProviderHolder holder = null;
6739
6740 try {
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006741 holder = getContentProviderExternalUnchecked(name, null);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006742 if (holder != null) {
6743 return holder.provider.getType(uri);
6744 }
6745 } catch (RemoteException e) {
6746 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6747 return null;
6748 } finally {
6749 if (holder != null) {
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006750 removeContentProviderExternalUnchecked(name, null);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006751 }
6752 Binder.restoreCallingIdentity(ident);
6753 }
6754
6755 return null;
6756 }
6757
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006758 // =========================================================
6759 // GLOBAL MANAGEMENT
6760 // =========================================================
6761
6762 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006763 ApplicationInfo info, String customProcess, boolean isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006764 String proc = customProcess != null ? customProcess : info.processName;
6765 BatteryStatsImpl.Uid.Proc ps = null;
6766 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006767 int uid = info.uid;
6768 if (isolated) {
6769 int userId = UserId.getUserId(uid);
6770 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6771 uid = 0;
6772 while (true) {
6773 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6774 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6775 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6776 }
6777 uid = UserId.getUid(userId, mNextIsolatedProcessUid);
6778 mNextIsolatedProcessUid++;
6779 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6780 // No process for this uid, use it.
6781 break;
6782 }
6783 stepsLeft--;
6784 if (stepsLeft <= 0) {
6785 return null;
6786 }
6787 }
6788 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006789 synchronized (stats) {
6790 ps = stats.getProcessStatsLocked(info.uid, proc);
6791 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006792 return new ProcessRecord(ps, thread, info, proc, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006793 }
6794
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006795 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6796 ProcessRecord app;
6797 if (!isolated) {
6798 app = getProcessRecordLocked(info.processName, info.uid);
6799 } else {
6800 app = null;
6801 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006802
6803 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006804 app = newProcessRecordLocked(null, info, null, isolated);
6805 mProcessNames.put(info.processName, app.uid, app);
6806 if (isolated) {
6807 mIsolatedProcesses.put(app.uid, app);
6808 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006809 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006810 }
6811
Dianne Hackborne7f97212011-02-24 14:40:20 -08006812 // This package really, really can not be stopped.
6813 try {
6814 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -07006815 info.packageName, false, UserId.getUserId(app.uid));
Dianne Hackborne7f97212011-02-24 14:40:20 -08006816 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006817 } catch (IllegalArgumentException e) {
6818 Slog.w(TAG, "Failed trying to unstop package "
6819 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006820 }
6821
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006822 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6823 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6824 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006825 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006826 }
6827 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6828 mPersistentStartingProcesses.add(app);
6829 startProcessLocked(app, "added application", app.processName);
6830 }
6831
6832 return app;
6833 }
6834
6835 public void unhandledBack() {
6836 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6837 "unhandledBack()");
6838
6839 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006840 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006841 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006842 TAG, "Performing unhandledBack(): stack size = " + count);
6843 if (count > 1) {
6844 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006845 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006846 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6847 Binder.restoreCallingIdentity(origId);
6848 }
6849 }
6850 }
6851
6852 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006853 enforceNotIsolatedCaller("openContentUri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006854 String name = uri.getAuthority();
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006855 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006856 ParcelFileDescriptor pfd = null;
6857 if (cph != null) {
6858 // We record the binder invoker's uid in thread-local storage before
6859 // going to the content provider to open the file. Later, in the code
6860 // that handles all permissions checks, we look for this uid and use
6861 // that rather than the Activity Manager's own uid. The effect is that
6862 // we do the check against the caller's permissions even though it looks
6863 // to the content provider like the Activity Manager itself is making
6864 // the request.
6865 sCallerIdentity.set(new Identity(
6866 Binder.getCallingPid(), Binder.getCallingUid()));
6867 try {
6868 pfd = cph.provider.openFile(uri, "r");
6869 } catch (FileNotFoundException e) {
6870 // do nothing; pfd will be returned null
6871 } finally {
6872 // Ensure that whatever happens, we clean up the identity state
6873 sCallerIdentity.remove();
6874 }
6875
6876 // We've got the fd now, so we're done with the provider.
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006877 removeContentProviderExternalUnchecked(name, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006878 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006879 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006880 }
6881 return pfd;
6882 }
6883
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006884 // Actually is sleeping or shutting down or whatever else in the future
6885 // is an inactive state.
6886 public boolean isSleeping() {
6887 return mSleeping || mShuttingDown;
6888 }
6889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 public void goingToSleep() {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006891 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6892 != PackageManager.PERMISSION_GRANTED) {
6893 throw new SecurityException("Requires permission "
6894 + android.Manifest.permission.DEVICE_POWER);
6895 }
6896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006897 synchronized(this) {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006898 mWentToSleep = true;
Jeff Brownc042ee22012-05-08 13:03:42 -07006899 updateEventDispatchingLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006900
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006901 if (!mSleeping) {
6902 mSleeping = true;
6903 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006904
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006905 // Initialize the wake times of all processes.
6906 checkExcessivePowerUsageLocked(false);
6907 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6908 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6909 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006911 }
6912 }
6913
Dianne Hackborn55280a92009-05-07 15:53:46 -07006914 public boolean shutdown(int timeout) {
6915 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6916 != PackageManager.PERMISSION_GRANTED) {
6917 throw new SecurityException("Requires permission "
6918 + android.Manifest.permission.SHUTDOWN);
6919 }
6920
6921 boolean timedout = false;
6922
6923 synchronized(this) {
6924 mShuttingDown = true;
Jeff Brownc042ee22012-05-08 13:03:42 -07006925 updateEventDispatchingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006926
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006927 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006928 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006929 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006930 while (mMainStack.mResumedActivity != null
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08006931 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006932 long delay = endTime - System.currentTimeMillis();
6933 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006934 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006935 timedout = true;
6936 break;
6937 }
6938 try {
6939 this.wait();
6940 } catch (InterruptedException e) {
6941 }
6942 }
6943 }
6944 }
6945
6946 mUsageStatsService.shutdown();
6947 mBatteryStatsService.shutdown();
6948
6949 return timedout;
6950 }
6951
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006952 public final void activitySlept(IBinder token) {
6953 if (localLOGV) Slog.v(
6954 TAG, "Activity slept: token=" + token);
6955
6956 ActivityRecord r = null;
6957
6958 final long origId = Binder.clearCallingIdentity();
6959
6960 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006961 r = mMainStack.isInStackLocked(token);
6962 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006963 mMainStack.activitySleptLocked(r);
6964 }
6965 }
6966
6967 Binder.restoreCallingIdentity(origId);
6968 }
6969
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006970 private void comeOutOfSleepIfNeededLocked() {
6971 if (!mWentToSleep && !mLockScreenShown) {
6972 if (mSleeping) {
6973 mSleeping = false;
6974 mMainStack.awakeFromSleepingLocked();
6975 mMainStack.resumeTopActivityLocked(null);
6976 }
6977 }
6978 }
6979
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006980 public void wakingUp() {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006981 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6982 != PackageManager.PERMISSION_GRANTED) {
6983 throw new SecurityException("Requires permission "
6984 + android.Manifest.permission.DEVICE_POWER);
6985 }
6986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006987 synchronized(this) {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006988 mWentToSleep = false;
Jeff Brownc042ee22012-05-08 13:03:42 -07006989 updateEventDispatchingLocked();
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006990 comeOutOfSleepIfNeededLocked();
6991 }
6992 }
6993
Jeff Brownc042ee22012-05-08 13:03:42 -07006994 private void updateEventDispatchingLocked() {
6995 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
6996 }
6997
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006998 public void setLockScreenShown(boolean shown) {
6999 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7000 != PackageManager.PERMISSION_GRANTED) {
7001 throw new SecurityException("Requires permission "
7002 + android.Manifest.permission.DEVICE_POWER);
7003 }
7004
7005 synchronized(this) {
7006 mLockScreenShown = shown;
7007 comeOutOfSleepIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007008 }
7009 }
7010
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007011 public void stopAppSwitches() {
7012 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7013 != PackageManager.PERMISSION_GRANTED) {
7014 throw new SecurityException("Requires permission "
7015 + android.Manifest.permission.STOP_APP_SWITCHES);
7016 }
7017
7018 synchronized(this) {
7019 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7020 + APP_SWITCH_DELAY_TIME;
7021 mDidAppSwitch = false;
7022 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7023 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7024 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7025 }
7026 }
7027
7028 public void resumeAppSwitches() {
7029 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7030 != PackageManager.PERMISSION_GRANTED) {
7031 throw new SecurityException("Requires permission "
7032 + android.Manifest.permission.STOP_APP_SWITCHES);
7033 }
7034
7035 synchronized(this) {
7036 // Note that we don't execute any pending app switches... we will
7037 // let those wait until either the timeout, or the next start
7038 // activity request.
7039 mAppSwitchesAllowedTime = 0;
7040 }
7041 }
7042
7043 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7044 String name) {
7045 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7046 return true;
7047 }
7048
7049 final int perm = checkComponentPermission(
7050 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08007051 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007052 if (perm == PackageManager.PERMISSION_GRANTED) {
7053 return true;
7054 }
7055
Joe Onorato8a9b2202010-02-26 18:56:32 -08007056 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007057 return false;
7058 }
7059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007060 public void setDebugApp(String packageName, boolean waitForDebugger,
7061 boolean persistent) {
7062 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7063 "setDebugApp()");
7064
7065 // Note that this is not really thread safe if there are multiple
7066 // callers into it at the same time, but that's not a situation we
7067 // care about.
7068 if (persistent) {
7069 final ContentResolver resolver = mContext.getContentResolver();
7070 Settings.System.putString(
7071 resolver, Settings.System.DEBUG_APP,
7072 packageName);
7073 Settings.System.putInt(
7074 resolver, Settings.System.WAIT_FOR_DEBUGGER,
7075 waitForDebugger ? 1 : 0);
7076 }
7077
7078 synchronized (this) {
7079 if (!persistent) {
7080 mOrigDebugApp = mDebugApp;
7081 mOrigWaitForDebugger = mWaitForDebugger;
7082 }
7083 mDebugApp = packageName;
7084 mWaitForDebugger = waitForDebugger;
7085 mDebugTransient = !persistent;
7086 if (packageName != null) {
7087 final long origId = Binder.clearCallingIdentity();
Amith Yamasani483f3b02012-03-13 16:08:00 -07007088 forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007089 Binder.restoreCallingIdentity(origId);
7090 }
7091 }
7092 }
7093
Siva Velusamy92a8b222012-03-09 16:24:04 -08007094 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7095 synchronized (this) {
7096 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7097 if (!isDebuggable) {
7098 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7099 throw new SecurityException("Process not debuggable: " + app.packageName);
7100 }
7101 }
7102
7103 mOpenGlTraceApp = processName;
7104 }
7105 }
7106
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007107 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7108 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7109 synchronized (this) {
7110 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7111 if (!isDebuggable) {
7112 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7113 throw new SecurityException("Process not debuggable: " + app.packageName);
7114 }
7115 }
7116 mProfileApp = processName;
7117 mProfileFile = profileFile;
7118 if (mProfileFd != null) {
7119 try {
7120 mProfileFd.close();
7121 } catch (IOException e) {
7122 }
7123 mProfileFd = null;
7124 }
7125 mProfileFd = profileFd;
7126 mProfileType = 0;
7127 mAutoStopProfiler = autoStopProfiler;
7128 }
7129 }
7130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007131 public void setAlwaysFinish(boolean enabled) {
7132 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7133 "setAlwaysFinish()");
7134
7135 Settings.System.putInt(
7136 mContext.getContentResolver(),
7137 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7138
7139 synchronized (this) {
7140 mAlwaysFinishActivities = enabled;
7141 }
7142 }
7143
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007144 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007145 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007146 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007147 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007148 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007149 }
7150 }
7151
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08007152 public boolean isUserAMonkey() {
7153 // For now the fact that there is a controller implies
7154 // we have a monkey.
7155 synchronized (this) {
7156 return mController != null;
7157 }
7158 }
7159
Jeff Sharkeya4620792011-05-20 15:29:23 -07007160 public void registerProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007161 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7162 "registerProcessObserver()");
7163 synchronized (this) {
7164 mProcessObservers.register(observer);
7165 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007166 }
7167
7168 public void unregisterProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007169 synchronized (this) {
7170 mProcessObservers.unregister(observer);
7171 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007172 }
7173
Daniel Sandler69a48172010-06-23 16:29:36 -04007174 public void setImmersive(IBinder token, boolean immersive) {
7175 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007176 ActivityRecord r = mMainStack.isInStackLocked(token);
7177 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007178 throw new IllegalArgumentException();
7179 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007180 r.immersive = immersive;
7181 }
7182 }
7183
7184 public boolean isImmersive(IBinder token) {
7185 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007186 ActivityRecord r = mMainStack.isInStackLocked(token);
7187 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007188 throw new IllegalArgumentException();
7189 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007190 return r.immersive;
7191 }
7192 }
7193
7194 public boolean isTopActivityImmersive() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007195 enforceNotIsolatedCaller("startActivity");
Daniel Sandler69a48172010-06-23 16:29:36 -04007196 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007197 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04007198 return (r != null) ? r.immersive : false;
7199 }
7200 }
7201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007202 public final void enterSafeMode() {
7203 synchronized(this) {
7204 // It only makes sense to do this before the system is ready
7205 // and started launching other packages.
7206 if (!mSystemReady) {
7207 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007208 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007209 } catch (RemoteException e) {
7210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007211 }
7212 }
7213 }
7214
Jeff Brownb09abc12011-01-13 21:08:27 -08007215 public final void showSafeModeOverlay() {
7216 View v = LayoutInflater.from(mContext).inflate(
7217 com.android.internal.R.layout.safe_mode, null);
7218 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7219 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7220 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7221 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
7222 lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
7223 lp.format = v.getBackground().getOpacity();
7224 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7225 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7226 ((WindowManager)mContext.getSystemService(
7227 Context.WINDOW_SERVICE)).addView(v, lp);
7228 }
7229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007230 public void noteWakeupAlarm(IIntentSender sender) {
7231 if (!(sender instanceof PendingIntentRecord)) {
7232 return;
7233 }
7234 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7235 synchronized (stats) {
7236 if (mBatteryStatsService.isOnBattery()) {
7237 mBatteryStatsService.enforceCallingPermission();
7238 PendingIntentRecord rec = (PendingIntentRecord)sender;
7239 int MY_UID = Binder.getCallingUid();
7240 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7241 BatteryStatsImpl.Uid.Pkg pkg =
7242 stats.getPackageStatsLocked(uid, rec.key.packageName);
7243 pkg.incWakeupsLocked();
7244 }
7245 }
7246 }
7247
Dianne Hackborn64825172011-03-02 21:32:58 -08007248 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007249 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007250 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007251 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007252 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007253 // XXX Note: don't acquire main activity lock here, because the window
7254 // manager calls in with its locks held.
7255
7256 boolean killed = false;
7257 synchronized (mPidsSelfLocked) {
7258 int[] types = new int[pids.length];
7259 int worstType = 0;
7260 for (int i=0; i<pids.length; i++) {
7261 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7262 if (proc != null) {
7263 int type = proc.setAdj;
7264 types[i] = type;
7265 if (type > worstType) {
7266 worstType = type;
7267 }
7268 }
7269 }
7270
Dianne Hackborn64825172011-03-02 21:32:58 -08007271 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007272 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007273 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7274 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07007275 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007276 }
Dianne Hackborn64825172011-03-02 21:32:58 -08007277
7278 // If this is not a secure call, don't let it kill processes that
7279 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007280 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7281 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08007282 }
7283
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007284 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007285 for (int i=0; i<pids.length; i++) {
7286 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7287 if (proc == null) {
7288 continue;
7289 }
7290 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007291 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007292 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007293 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7294 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007295 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007296 proc.killedBackground = true;
7297 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007298 }
7299 }
7300 }
7301 return killed;
7302 }
Jeff Sharkeyb9a07012012-03-22 17:00:04 -07007303
7304 @Override
7305 public boolean killProcessesBelowForeground(String reason) {
7306 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7307 throw new SecurityException("killProcessesBelowForeground() only available to system");
7308 }
7309
7310 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7311 }
7312
7313 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7314 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7315 throw new SecurityException("killProcessesBelowAdj() only available to system");
7316 }
7317
7318 boolean killed = false;
7319 synchronized (mPidsSelfLocked) {
7320 final int size = mPidsSelfLocked.size();
7321 for (int i = 0; i < size; i++) {
7322 final int pid = mPidsSelfLocked.keyAt(i);
7323 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7324 if (proc == null) continue;
7325
7326 final int adj = proc.setAdj;
7327 if (adj > belowAdj && !proc.killedBackground) {
7328 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7329 EventLog.writeEvent(
7330 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7331 killed = true;
7332 proc.killedBackground = true;
7333 Process.killProcessQuiet(pid);
7334 }
7335 }
7336 }
7337 return killed;
7338 }
7339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007340 public final void startRunning(String pkg, String cls, String action,
7341 String data) {
7342 synchronized(this) {
7343 if (mStartRunning) {
7344 return;
7345 }
7346 mStartRunning = true;
7347 mTopComponent = pkg != null && cls != null
7348 ? new ComponentName(pkg, cls) : null;
7349 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7350 mTopData = data;
7351 if (!mSystemReady) {
7352 return;
7353 }
7354 }
7355
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007356 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007357 }
7358
7359 private void retrieveSettings() {
7360 final ContentResolver resolver = mContext.getContentResolver();
7361 String debugApp = Settings.System.getString(
7362 resolver, Settings.System.DEBUG_APP);
7363 boolean waitForDebugger = Settings.System.getInt(
7364 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7365 boolean alwaysFinishActivities = Settings.System.getInt(
7366 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7367
7368 Configuration configuration = new Configuration();
7369 Settings.System.getConfiguration(resolver, configuration);
7370
7371 synchronized (this) {
7372 mDebugApp = mOrigDebugApp = debugApp;
7373 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7374 mAlwaysFinishActivities = alwaysFinishActivities;
7375 // This happens before any activities are started, so we can
7376 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08007377 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007378 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007379 }
7380 }
7381
7382 public boolean testIsSystemReady() {
7383 // no need to synchronize(this) just to read & return the value
7384 return mSystemReady;
7385 }
7386
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007387 private static File getCalledPreBootReceiversFile() {
7388 File dataDir = Environment.getDataDirectory();
7389 File systemDir = new File(dataDir, "system");
7390 File fname = new File(systemDir, "called_pre_boots.dat");
7391 return fname;
7392 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007393
7394 static final int LAST_DONE_VERSION = 10000;
7395
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007396 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7397 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7398 File file = getCalledPreBootReceiversFile();
7399 FileInputStream fis = null;
7400 try {
7401 fis = new FileInputStream(file);
7402 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007403 int fvers = dis.readInt();
7404 if (fvers == LAST_DONE_VERSION) {
7405 String vers = dis.readUTF();
7406 String codename = dis.readUTF();
7407 String build = dis.readUTF();
7408 if (android.os.Build.VERSION.RELEASE.equals(vers)
7409 && android.os.Build.VERSION.CODENAME.equals(codename)
7410 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7411 int num = dis.readInt();
7412 while (num > 0) {
7413 num--;
7414 String pkg = dis.readUTF();
7415 String cls = dis.readUTF();
7416 lastDoneReceivers.add(new ComponentName(pkg, cls));
7417 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007418 }
7419 }
7420 } catch (FileNotFoundException e) {
7421 } catch (IOException e) {
7422 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7423 } finally {
7424 if (fis != null) {
7425 try {
7426 fis.close();
7427 } catch (IOException e) {
7428 }
7429 }
7430 }
7431 return lastDoneReceivers;
7432 }
7433
7434 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7435 File file = getCalledPreBootReceiversFile();
7436 FileOutputStream fos = null;
7437 DataOutputStream dos = null;
7438 try {
7439 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7440 fos = new FileOutputStream(file);
7441 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007442 dos.writeInt(LAST_DONE_VERSION);
7443 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007444 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007445 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007446 dos.writeInt(list.size());
7447 for (int i=0; i<list.size(); i++) {
7448 dos.writeUTF(list.get(i).getPackageName());
7449 dos.writeUTF(list.get(i).getClassName());
7450 }
7451 } catch (IOException e) {
7452 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7453 file.delete();
7454 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07007455 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007456 if (dos != null) {
7457 try {
7458 dos.close();
7459 } catch (IOException e) {
7460 // TODO Auto-generated catch block
7461 e.printStackTrace();
7462 }
7463 }
7464 }
7465 }
7466
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007467 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007468 synchronized(this) {
7469 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007470 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007471 return;
7472 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007473
7474 // Check to see if there are any update receivers to run.
7475 if (!mDidUpdate) {
7476 if (mWaitingUpdate) {
7477 return;
7478 }
7479 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7480 List<ResolveInfo> ris = null;
7481 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007482 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Amith Yamasani483f3b02012-03-13 16:08:00 -07007483 intent, null, 0, 0);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007484 } catch (RemoteException e) {
7485 }
7486 if (ris != null) {
7487 for (int i=ris.size()-1; i>=0; i--) {
7488 if ((ris.get(i).activityInfo.applicationInfo.flags
7489 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7490 ris.remove(i);
7491 }
7492 }
7493 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007494
7495 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7496
7497 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007498 for (int i=0; i<ris.size(); i++) {
7499 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007500 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7501 if (lastDoneReceivers.contains(comp)) {
7502 ris.remove(i);
7503 i--;
7504 }
7505 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007506
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007507 for (int i=0; i<ris.size(); i++) {
7508 ActivityInfo ai = ris.get(i).activityInfo;
7509 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7510 doneReceivers.add(comp);
7511 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007512 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08007513 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007514 finisher = new IIntentReceiver.Stub() {
7515 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07007516 String data, Bundle extras, boolean ordered,
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007517 boolean sticky) {
7518 // The raw IIntentReceiver interface is called
7519 // with the AM lock held, so redispatch to
7520 // execute our code without the lock.
7521 mHandler.post(new Runnable() {
7522 public void run() {
7523 synchronized (ActivityManagerService.this) {
7524 mDidUpdate = true;
7525 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007526 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007527 showBootMessage(mContext.getText(
7528 R.string.android_upgrading_complete),
7529 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007530 systemReady(goingCallback);
7531 }
7532 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007533 }
7534 };
7535 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007536 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Amith Yamasani742a6712011-05-04 14:49:28 -07007537 /* TODO: Send this to all users */
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007538 broadcastIntentLocked(null, null, intent, null, finisher,
Amith Yamasani742a6712011-05-04 14:49:28 -07007539 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
Amith Yamasanic600e21f2012-02-14 16:08:07 -08007540 0 /* UserId zero */);
Dianne Hackbornd6847842010-01-12 18:14:19 -08007541 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007542 mWaitingUpdate = true;
7543 }
7544 }
7545 }
7546 if (mWaitingUpdate) {
7547 return;
7548 }
7549 mDidUpdate = true;
7550 }
7551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007552 mSystemReady = true;
7553 if (!mStartRunning) {
7554 return;
7555 }
7556 }
7557
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007558 ArrayList<ProcessRecord> procsToKill = null;
7559 synchronized(mPidsSelfLocked) {
7560 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7561 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7562 if (!isAllowedWhileBooting(proc.info)){
7563 if (procsToKill == null) {
7564 procsToKill = new ArrayList<ProcessRecord>();
7565 }
7566 procsToKill.add(proc);
7567 }
7568 }
7569 }
7570
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007571 synchronized(this) {
7572 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007573 for (int i=procsToKill.size()-1; i>=0; i--) {
7574 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007575 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007576 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007577 }
7578 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007579
7580 // Now that we have cleaned up any update processes, we
7581 // are ready to start launching real processes and know that
7582 // we won't trample on them any more.
7583 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007584 }
7585
Joe Onorato8a9b2202010-02-26 18:56:32 -08007586 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007587 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007588 SystemClock.uptimeMillis());
7589
7590 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007591 // Make sure we have no pre-ready processes sitting around.
7592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007593 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7594 ResolveInfo ri = mContext.getPackageManager()
7595 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007596 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007597 CharSequence errorMsg = null;
7598 if (ri != null) {
7599 ActivityInfo ai = ri.activityInfo;
7600 ApplicationInfo app = ai.applicationInfo;
7601 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7602 mTopAction = Intent.ACTION_FACTORY_TEST;
7603 mTopData = null;
7604 mTopComponent = new ComponentName(app.packageName,
7605 ai.name);
7606 } else {
7607 errorMsg = mContext.getResources().getText(
7608 com.android.internal.R.string.factorytest_not_system);
7609 }
7610 } else {
7611 errorMsg = mContext.getResources().getText(
7612 com.android.internal.R.string.factorytest_no_action);
7613 }
7614 if (errorMsg != null) {
7615 mTopAction = null;
7616 mTopData = null;
7617 mTopComponent = null;
7618 Message msg = Message.obtain();
7619 msg.what = SHOW_FACTORY_ERROR_MSG;
7620 msg.getData().putCharSequence("msg", errorMsg);
7621 mHandler.sendMessage(msg);
7622 }
7623 }
7624 }
7625
7626 retrieveSettings();
7627
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007628 if (goingCallback != null) goingCallback.run();
7629
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007630 synchronized (this) {
7631 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7632 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007633 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007634 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007635 if (apps != null) {
7636 int N = apps.size();
7637 int i;
7638 for (i=0; i<N; i++) {
7639 ApplicationInfo info
7640 = (ApplicationInfo)apps.get(i);
7641 if (info != null &&
7642 !info.packageName.equals("android")) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007643 addAppLocked(info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007644 }
7645 }
7646 }
7647 } catch (RemoteException ex) {
7648 // pm is in same process, this will never happen.
7649 }
7650 }
7651
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007652 // Start up initial activity.
7653 mBooting = true;
7654
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007655 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007656 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007657 Message msg = Message.obtain();
7658 msg.what = SHOW_UID_ERROR_MSG;
7659 mHandler.sendMessage(msg);
7660 }
7661 } catch (RemoteException e) {
7662 }
7663
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007664 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007665 }
7666 }
7667
Dan Egnorb7f03672009-12-09 16:22:32 -08007668 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007669 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007670 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007671 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007672 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007673 startAppProblemLocked(app);
7674 app.stopFreezingAllLocked();
7675 return handleAppCrashLocked(app);
7676 }
7677
Dan Egnorb7f03672009-12-09 16:22:32 -08007678 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007679 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007680 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007681 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007682 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7683 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007684 startAppProblemLocked(app);
7685 app.stopFreezingAllLocked();
7686 }
7687
7688 /**
7689 * Generate a process error record, suitable for attachment to a ProcessRecord.
7690 *
7691 * @param app The ProcessRecord in which the error occurred.
7692 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7693 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007694 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007695 * @param shortMsg Short message describing the crash.
7696 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007697 * @param stackTrace Full crash stack trace, may be null.
7698 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007699 * @return Returns a fully-formed AppErrorStateInfo record.
7700 */
7701 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007702 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007703 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007705 report.condition = condition;
7706 report.processName = app.processName;
7707 report.pid = app.pid;
7708 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007709 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007710 report.shortMsg = shortMsg;
7711 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007712 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007713
7714 return report;
7715 }
7716
Dan Egnor42471dd2010-01-07 17:25:22 -08007717 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007718 synchronized (this) {
7719 app.crashing = false;
7720 app.crashingReport = null;
7721 app.notResponding = false;
7722 app.notRespondingReport = null;
7723 if (app.anrDialog == fromDialog) {
7724 app.anrDialog = null;
7725 }
7726 if (app.waitDialog == fromDialog) {
7727 app.waitDialog = null;
7728 }
7729 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007730 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007731 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007732 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7733 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007734 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007736 }
7737 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007738
Dan Egnorb7f03672009-12-09 16:22:32 -08007739 private boolean handleAppCrashLocked(ProcessRecord app) {
Mike Lockwood86548c42011-09-13 17:21:46 -04007740 if (mHeadless) {
7741 Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7742 return false;
7743 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007744 long now = SystemClock.uptimeMillis();
7745
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007746 Long crashTime;
7747 if (!app.isolated) {
7748 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7749 } else {
7750 crashTime = null;
7751 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007752 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007753 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007754 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007755 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007756 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007757 app.info.processName, app.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007758 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7759 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007760 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007761 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007762 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007763 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007764 }
7765 }
7766 if (!app.persistent) {
7767 // We don't want to start this process again until the user
7768 // explicitly does so... but for persistent process, we really
7769 // need to keep it running. If a persistent process is actually
7770 // repeatedly crashing, then badness for everyone.
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007771 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772 app.info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007773 if (!app.isolated) {
7774 // XXX We don't have a way to mark isolated processes
7775 // as bad, since they don't have a peristent identity.
7776 mBadProcesses.put(app.info.processName, app.uid, now);
7777 mProcessCrashTimes.remove(app.info.processName, app.uid);
7778 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007779 app.bad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007780 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007781 // Don't let services in this process be restarted and potentially
7782 // annoy the user repeatedly. Unless it is persistent, since those
7783 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007784 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007785 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007786 return false;
7787 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007788 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007789 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007790 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Kevin Hester-Chowd87a9be2012-03-05 08:01:00 -08007791 if (r != null && r.app == app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007792 // If the top running activity is from this crashing
7793 // process, then terminate it to avoid getting in a loop.
7794 Slog.w(TAG, " Force finishing activity "
7795 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007796 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007797 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007798 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007799 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007800 // stopped, to avoid a situation where one will get
7801 // re-start our crashing activity once it gets resumed again.
7802 index--;
7803 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007804 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007805 if (r.state == ActivityState.RESUMED
7806 || r.state == ActivityState.PAUSING
7807 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007808 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007809 Slog.w(TAG, " Force finishing activity "
7810 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007811 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007812 Activity.RESULT_CANCELED, null, "crashed");
7813 }
7814 }
7815 }
7816 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817 }
7818
7819 // Bump up the crash count of any services currently running in the proc.
7820 if (app.services.size() != 0) {
7821 // Any services running in the application need to be placed
7822 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007823 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007824 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007825 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007826 sr.crashCount++;
7827 }
7828 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007829
7830 // If the crashing process is what we consider to be the "home process" and it has been
7831 // replaced by a third-party app, clear the package preferred activities from packages
7832 // with a home activity running in the process to prevent a repeatedly crashing app
7833 // from blocking the user to manually clear the list.
7834 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7835 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7836 Iterator it = mHomeProcess.activities.iterator();
7837 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007838 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007839 if (r.isHomeActivity) {
7840 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7841 try {
7842 ActivityThread.getPackageManager()
7843 .clearPackagePreferredActivities(r.packageName);
7844 } catch (RemoteException c) {
7845 // pm is in same process, this will never happen.
7846 }
7847 }
7848 }
7849 }
7850
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007851 if (!app.isolated) {
7852 // XXX Can't keep track of crash times for isolated processes,
7853 // because they don't have a perisistent identity.
7854 mProcessCrashTimes.put(app.info.processName, app.uid, now);
7855 }
7856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007857 return true;
7858 }
7859
7860 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007861 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7862 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007863 skipCurrentReceiverLocked(app);
7864 }
7865
7866 void skipCurrentReceiverLocked(ProcessRecord app) {
Christopher Tatef46723b2012-01-26 14:19:24 -08007867 for (BroadcastQueue queue : mBroadcastQueues) {
7868 queue.skipCurrentReceiverLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007869 }
7870 }
7871
Dan Egnor60d87622009-12-16 16:32:58 -08007872 /**
7873 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7874 * The application process will exit immediately after this call returns.
7875 * @param app object of the crashing app, null for the system server
7876 * @param crashInfo describing the exception
7877 */
7878 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007879 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007880 final String processName = app == null ? "system_server"
7881 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007882
7883 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007884 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007885 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007886 crashInfo.exceptionClassName,
7887 crashInfo.exceptionMessage,
7888 crashInfo.throwFileName,
7889 crashInfo.throwLineNumber);
7890
Jeff Sharkeya353d262011-10-28 11:12:06 -07007891 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007892
7893 crashApplication(r, crashInfo);
7894 }
7895
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007896 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007897 IBinder app,
7898 int violationMask,
7899 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007900 ProcessRecord r = findAppProcess(app, "StrictMode");
7901 if (r == null) {
7902 return;
7903 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007904
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007905 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007906 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007907 boolean logIt = true;
7908 synchronized (mAlreadyLoggedViolatedStacks) {
7909 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7910 logIt = false;
7911 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007912 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007913 // the relative pain numbers, without logging all
7914 // the stack traces repeatedly. We'd want to do
7915 // likewise in the client code, which also does
7916 // dup suppression, before the Binder call.
7917 } else {
7918 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7919 mAlreadyLoggedViolatedStacks.clear();
7920 }
7921 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7922 }
7923 }
7924 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007925 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007926 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007927 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007928
7929 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7930 AppErrorResult result = new AppErrorResult();
7931 synchronized (this) {
7932 final long origId = Binder.clearCallingIdentity();
7933
7934 Message msg = Message.obtain();
7935 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7936 HashMap<String, Object> data = new HashMap<String, Object>();
7937 data.put("result", result);
7938 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007939 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007940 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007941 msg.obj = data;
7942 mHandler.sendMessage(msg);
7943
7944 Binder.restoreCallingIdentity(origId);
7945 }
7946 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007947 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007948 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007949 }
7950
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007951 // Depending on the policy in effect, there could be a bunch of
7952 // these in quick succession so we try to batch these together to
7953 // minimize disk writes, number of dropbox entries, and maximize
7954 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007955 private void logStrictModeViolationToDropBox(
7956 ProcessRecord process,
7957 StrictMode.ViolationInfo info) {
7958 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007959 return;
7960 }
7961 final boolean isSystemApp = process == null ||
7962 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7963 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007964 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007965 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
7966 final DropBoxManager dbox = (DropBoxManager)
7967 mContext.getSystemService(Context.DROPBOX_SERVICE);
7968
7969 // Exit early if the dropbox isn't configured to accept this report type.
7970 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
7971
7972 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07007973 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007974 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
7975 synchronized (sb) {
7976 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07007977 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007978 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
7979 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007980 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
7981 if (info.violationNumThisLoop != 0) {
7982 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
7983 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07007984 if (info.numAnimationsRunning != 0) {
7985 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
7986 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07007987 if (info.broadcastIntentAction != null) {
7988 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
7989 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007990 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007991 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007992 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08007993 if (info.numInstances != -1) {
7994 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
7995 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08007996 if (info.tags != null) {
7997 for (String tag : info.tags) {
7998 sb.append("Span-Tag: ").append(tag).append("\n");
7999 }
8000 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008001 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008002 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8003 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008004 }
8005 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008006
8007 // Only buffer up to ~64k. Various logging bits truncate
8008 // things at 128k.
8009 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008010 }
8011
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008012 // Flush immediately if the buffer's grown too large, or this
8013 // is a non-system app. Non-system apps are isolated with a
8014 // different tag & policy and not batched.
8015 //
8016 // Batching is useful during internal testing with
8017 // StrictMode settings turned up high. Without batching,
8018 // thousands of separate files could be created on boot.
8019 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008020 new Thread("Error dump: " + dropboxTag) {
8021 @Override
8022 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008023 String report;
8024 synchronized (sb) {
8025 report = sb.toString();
8026 sb.delete(0, sb.length());
8027 sb.trimToSize();
8028 }
8029 if (report.length() != 0) {
8030 dbox.addText(dropboxTag, report);
8031 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008032 }
8033 }.start();
8034 return;
8035 }
8036
8037 // System app batching:
8038 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008039 // An existing dropbox-writing thread is outstanding, so
8040 // we don't need to start it up. The existing thread will
8041 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008042 return;
8043 }
8044
8045 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8046 // (After this point, we shouldn't access AMS internal data structures.)
8047 new Thread("Error dump: " + dropboxTag) {
8048 @Override
8049 public void run() {
8050 // 5 second sleep to let stacks arrive and be batched together
8051 try {
8052 Thread.sleep(5000); // 5 seconds
8053 } catch (InterruptedException e) {}
8054
8055 String errorReport;
8056 synchronized (mStrictModeBuffer) {
8057 errorReport = mStrictModeBuffer.toString();
8058 if (errorReport.length() == 0) {
8059 return;
8060 }
8061 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8062 mStrictModeBuffer.trimToSize();
8063 }
8064 dbox.addText(dropboxTag, errorReport);
8065 }
8066 }.start();
8067 }
8068
Dan Egnor60d87622009-12-16 16:32:58 -08008069 /**
8070 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8071 * @param app object of the crashing app, null for the system server
8072 * @param tag reported by the caller
8073 * @param crashInfo describing the context of the error
8074 * @return true if the process should exit immediately (WTF is fatal)
8075 */
8076 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08008077 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008078 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008079 final String processName = app == null ? "system_server"
8080 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008081
8082 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008083 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008084 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008085 tag, crashInfo.exceptionMessage);
8086
Jeff Sharkeya353d262011-10-28 11:12:06 -07008087 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008088
Dianne Hackborn1ab43772011-03-15 14:38:02 -07008089 if (r != null && r.pid != Process.myPid() &&
8090 Settings.Secure.getInt(mContext.getContentResolver(),
8091 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08008092 crashApplication(r, crashInfo);
8093 return true;
8094 } else {
8095 return false;
8096 }
8097 }
8098
8099 /**
8100 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8101 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8102 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08008103 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08008104 if (app == null) {
8105 return null;
8106 }
8107
8108 synchronized (this) {
8109 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8110 final int NA = apps.size();
8111 for (int ia=0; ia<NA; ia++) {
8112 ProcessRecord p = apps.valueAt(ia);
8113 if (p.thread != null && p.thread.asBinder() == app) {
8114 return p;
8115 }
8116 }
8117 }
8118
Dianne Hackborncb44d962011-03-10 17:02:27 -08008119 Slog.w(TAG, "Can't find mystery application for " + reason
8120 + " from pid=" + Binder.getCallingPid()
8121 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08008122 return null;
8123 }
8124 }
8125
8126 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008127 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8128 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08008129 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07008130 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8131 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008132 // Watchdog thread ends up invoking this function (with
8133 // a null ProcessRecord) to add the stack file to dropbox.
8134 // Do not acquire a lock on this (am) in such cases, as it
8135 // could cause a potential deadlock, if and when watchdog
8136 // is invoked due to unavailability of lock on am and it
8137 // would prevent watchdog from killing system_server.
8138 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008139 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008140 return;
8141 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07008142 // Note: ProcessRecord 'process' is guarded by the service
8143 // instance. (notably process.pkgList, which could otherwise change
8144 // concurrently during execution of this method)
8145 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008146 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08008147 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008148 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08008149 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8150 for (String pkg : process.pkgList) {
8151 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08008152 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07008153 PackageInfo pi = pm.getPackageInfo(pkg, 0, 0);
Dan Egnora455d192010-03-12 08:52:28 -08008154 if (pi != null) {
8155 sb.append(" v").append(pi.versionCode);
8156 if (pi.versionName != null) {
8157 sb.append(" (").append(pi.versionName).append(")");
8158 }
8159 }
8160 } catch (RemoteException e) {
8161 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08008162 }
Dan Egnora455d192010-03-12 08:52:28 -08008163 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08008164 }
Dan Egnora455d192010-03-12 08:52:28 -08008165 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008166 }
8167
8168 private static String processClass(ProcessRecord process) {
8169 if (process == null || process.pid == MY_PID) {
8170 return "system_server";
8171 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8172 return "system_app";
8173 } else {
8174 return "data_app";
8175 }
8176 }
8177
8178 /**
8179 * Write a description of an error (crash, WTF, ANR) to the drop box.
8180 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8181 * @param process which caused the error, null means the system server
8182 * @param activity which triggered the error, null if unknown
8183 * @param parent activity related to the error, null if unknown
8184 * @param subject line related to the error, null if absent
8185 * @param report in long form describing the error, null if absent
8186 * @param logFile to include in the report, null if none
8187 * @param crashInfo giving an application stack trace, null if absent
8188 */
8189 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07008190 ProcessRecord process, String processName, ActivityRecord activity,
8191 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008192 final String report, final File logFile,
8193 final ApplicationErrorReport.CrashInfo crashInfo) {
8194 // NOTE -- this must never acquire the ActivityManagerService lock,
8195 // otherwise the watchdog may be prevented from resetting the system.
8196
8197 final String dropboxTag = processClass(process) + "_" + eventType;
8198 final DropBoxManager dbox = (DropBoxManager)
8199 mContext.getSystemService(Context.DROPBOX_SERVICE);
8200
8201 // Exit early if the dropbox isn't configured to accept this report type.
8202 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8203
8204 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07008205 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08008206 if (activity != null) {
8207 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8208 }
8209 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8210 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8211 }
8212 if (parent != null && parent != activity) {
8213 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8214 }
8215 if (subject != null) {
8216 sb.append("Subject: ").append(subject).append("\n");
8217 }
8218 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02008219 if (Debug.isDebuggerConnected()) {
8220 sb.append("Debugger: Connected\n");
8221 }
Dan Egnora455d192010-03-12 08:52:28 -08008222 sb.append("\n");
8223
8224 // Do the rest in a worker thread to avoid blocking the caller on I/O
8225 // (After this point, we shouldn't access AMS internal data structures.)
8226 Thread worker = new Thread("Error dump: " + dropboxTag) {
8227 @Override
8228 public void run() {
8229 if (report != null) {
8230 sb.append(report);
8231 }
8232 if (logFile != null) {
8233 try {
8234 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8235 } catch (IOException e) {
8236 Slog.e(TAG, "Error reading " + logFile, e);
8237 }
8238 }
8239 if (crashInfo != null && crashInfo.stackTrace != null) {
8240 sb.append(crashInfo.stackTrace);
8241 }
8242
8243 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8244 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8245 if (lines > 0) {
8246 sb.append("\n");
8247
8248 // Merge several logcat streams, and take the last N lines
8249 InputStreamReader input = null;
8250 try {
8251 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8252 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8253 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8254
8255 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8256 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8257 input = new InputStreamReader(logcat.getInputStream());
8258
8259 int num;
8260 char[] buf = new char[8192];
8261 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8262 } catch (IOException e) {
8263 Slog.e(TAG, "Error running logcat", e);
8264 } finally {
8265 if (input != null) try { input.close(); } catch (IOException e) {}
8266 }
8267 }
8268
8269 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08008270 }
Dan Egnora455d192010-03-12 08:52:28 -08008271 };
8272
Dianne Hackborn56385cc2012-04-30 15:07:47 -07008273 if (process == null) {
8274 // If process is null, we are being called from some internal code
8275 // and may be about to die -- run this synchronously.
8276 worker.run();
Dan Egnora455d192010-03-12 08:52:28 -08008277 } else {
8278 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08008279 }
8280 }
8281
8282 /**
8283 * Bring up the "unexpected error" dialog box for a crashing app.
8284 * Deal with edge cases (intercepts from instrumented applications,
8285 * ActivityController, error intent receivers, that sort of thing).
8286 * @param r the application crashing
8287 * @param crashInfo describing the failure
8288 */
8289 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008290 long timeMillis = System.currentTimeMillis();
8291 String shortMsg = crashInfo.exceptionClassName;
8292 String longMsg = crashInfo.exceptionMessage;
8293 String stackTrace = crashInfo.stackTrace;
8294 if (shortMsg != null && longMsg != null) {
8295 longMsg = shortMsg + ": " + longMsg;
8296 } else if (shortMsg != null) {
8297 longMsg = shortMsg;
8298 }
8299
Dan Egnor60d87622009-12-16 16:32:58 -08008300 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008301 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008302 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008303 try {
8304 String name = r != null ? r.processName : null;
8305 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08008306 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08008307 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008308 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008309 + " at watcher's request");
8310 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08008311 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008312 }
8313 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008314 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008315 }
8316 }
8317
8318 final long origId = Binder.clearCallingIdentity();
8319
8320 // If this process is running instrumentation, finish it.
8321 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008322 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008323 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08008324 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8325 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008326 Bundle info = new Bundle();
8327 info.putString("shortMsg", shortMsg);
8328 info.putString("longMsg", longMsg);
8329 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8330 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008331 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008332 }
8333
Dan Egnor60d87622009-12-16 16:32:58 -08008334 // If we can't identify the process or it's already exceeded its crash quota,
8335 // quit right away without showing a crash dialog.
8336 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008337 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008338 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008339 }
8340
8341 Message msg = Message.obtain();
8342 msg.what = SHOW_ERROR_MSG;
8343 HashMap data = new HashMap();
8344 data.put("result", result);
8345 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008346 msg.obj = data;
8347 mHandler.sendMessage(msg);
8348
8349 Binder.restoreCallingIdentity(origId);
8350 }
8351
8352 int res = result.get();
8353
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008354 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008355 synchronized (this) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008356 if (r != null && !r.isolated) {
8357 // XXX Can't keep track of crash time for isolated processes,
8358 // since they don't have a persistent identity.
8359 mProcessCrashTimes.put(r.info.processName, r.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008360 SystemClock.uptimeMillis());
8361 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008362 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008363 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008364 }
8365 }
8366
8367 if (appErrorIntent != null) {
8368 try {
8369 mContext.startActivity(appErrorIntent);
8370 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008371 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008372 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008374 }
Dan Egnorb7f03672009-12-09 16:22:32 -08008375
8376 Intent createAppErrorIntentLocked(ProcessRecord r,
8377 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8378 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008379 if (report == null) {
8380 return null;
8381 }
8382 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8383 result.setComponent(r.errorReportReceiver);
8384 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8385 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8386 return result;
8387 }
8388
Dan Egnorb7f03672009-12-09 16:22:32 -08008389 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8390 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008391 if (r.errorReportReceiver == null) {
8392 return null;
8393 }
8394
8395 if (!r.crashing && !r.notResponding) {
8396 return null;
8397 }
8398
Dan Egnorb7f03672009-12-09 16:22:32 -08008399 ApplicationErrorReport report = new ApplicationErrorReport();
8400 report.packageName = r.info.packageName;
8401 report.installerPackageName = r.errorReportReceiver.getPackageName();
8402 report.processName = r.processName;
8403 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01008404 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008405
Dan Egnorb7f03672009-12-09 16:22:32 -08008406 if (r.crashing) {
8407 report.type = ApplicationErrorReport.TYPE_CRASH;
8408 report.crashInfo = crashInfo;
8409 } else if (r.notResponding) {
8410 report.type = ApplicationErrorReport.TYPE_ANR;
8411 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008412
Dan Egnorb7f03672009-12-09 16:22:32 -08008413 report.anrInfo.activity = r.notRespondingReport.tag;
8414 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8415 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008416 }
8417
Dan Egnorb7f03672009-12-09 16:22:32 -08008418 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008419 }
8420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008421 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008422 enforceNotIsolatedCaller("getProcessesInErrorState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008423 // assume our apps are happy - lazy create the list
8424 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8425
8426 synchronized (this) {
8427
8428 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008429 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8430 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008431 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8432 // This one's in trouble, so we'll generate a report for it
8433 // crashes are higher priority (in case there's a crash *and* an anr)
8434 ActivityManager.ProcessErrorStateInfo report = null;
8435 if (app.crashing) {
8436 report = app.crashingReport;
8437 } else if (app.notResponding) {
8438 report = app.notRespondingReport;
8439 }
8440
8441 if (report != null) {
8442 if (errList == null) {
8443 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8444 }
8445 errList.add(report);
8446 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008447 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008448 " crashing = " + app.crashing +
8449 " notResponding = " + app.notResponding);
8450 }
8451 }
8452 }
8453 }
8454
8455 return errList;
8456 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07008457
8458 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008459 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008460 if (currApp != null) {
8461 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8462 }
8463 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008464 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8465 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008466 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8467 if (currApp != null) {
8468 currApp.lru = 0;
8469 }
8470 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008471 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008472 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8473 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8474 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8475 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8476 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8477 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8478 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8479 } else {
8480 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8481 }
8482 }
8483
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008484 private void fillInProcMemInfo(ProcessRecord app,
8485 ActivityManager.RunningAppProcessInfo outInfo) {
8486 outInfo.pid = app.pid;
8487 outInfo.uid = app.info.uid;
8488 if (mHeavyWeightProcess == app) {
8489 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8490 }
8491 if (app.persistent) {
8492 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8493 }
8494 outInfo.lastTrimLevel = app.trimMemoryLevel;
8495 int adj = app.curAdj;
8496 outInfo.importance = oomAdjToImportance(adj, outInfo);
8497 outInfo.importanceReasonCode = app.adjTypeCode;
8498 }
8499
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008500 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008501 enforceNotIsolatedCaller("getRunningAppProcesses");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008502 // Lazy instantiation of list
8503 List<ActivityManager.RunningAppProcessInfo> runList = null;
8504 synchronized (this) {
8505 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008506 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8507 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008508 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8509 // Generate process state info for running application
8510 ActivityManager.RunningAppProcessInfo currApp =
8511 new ActivityManager.RunningAppProcessInfo(app.processName,
8512 app.pid, app.getPackageList());
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008513 fillInProcMemInfo(app, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008514 if (app.adjSource instanceof ProcessRecord) {
8515 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008516 currApp.importanceReasonImportance = oomAdjToImportance(
8517 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008518 } else if (app.adjSource instanceof ActivityRecord) {
8519 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008520 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8521 }
8522 if (app.adjTarget instanceof ComponentName) {
8523 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8524 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008525 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008526 // + " lru=" + currApp.lru);
8527 if (runList == null) {
8528 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8529 }
8530 runList.add(currApp);
8531 }
8532 }
8533 }
8534 return runList;
8535 }
8536
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008537 public List<ApplicationInfo> getRunningExternalApplications() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008538 enforceNotIsolatedCaller("getRunningExternalApplications");
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008539 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8540 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8541 if (runningApps != null && runningApps.size() > 0) {
8542 Set<String> extList = new HashSet<String>();
8543 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8544 if (app.pkgList != null) {
8545 for (String pkg : app.pkgList) {
8546 extList.add(pkg);
8547 }
8548 }
8549 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008550 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008551 for (String pkg : extList) {
8552 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07008553 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserId.getCallingUserId());
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008554 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8555 retList.add(info);
8556 }
8557 } catch (RemoteException e) {
8558 }
8559 }
8560 }
8561 return retList;
8562 }
8563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008564 @Override
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008565 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8566 enforceNotIsolatedCaller("getMyMemoryState");
8567 synchronized (this) {
8568 ProcessRecord proc;
8569 synchronized (mPidsSelfLocked) {
8570 proc = mPidsSelfLocked.get(Binder.getCallingPid());
8571 }
8572 fillInProcMemInfo(proc, outInfo);
8573 }
8574 }
8575
8576 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008577 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008578 if (checkCallingPermission(android.Manifest.permission.DUMP)
8579 != PackageManager.PERMISSION_GRANTED) {
8580 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8581 + Binder.getCallingPid()
8582 + ", uid=" + Binder.getCallingUid()
8583 + " without permission "
8584 + android.Manifest.permission.DUMP);
8585 return;
8586 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008587
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008588 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008589 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008590 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008591
8592 int opti = 0;
8593 while (opti < args.length) {
8594 String opt = args[opti];
8595 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8596 break;
8597 }
8598 opti++;
8599 if ("-a".equals(opt)) {
8600 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008601 } else if ("-c".equals(opt)) {
8602 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008603 } else if ("-h".equals(opt)) {
8604 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008605 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008606 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008607 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008608 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
8609 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8610 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008611 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008612 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08008613 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008614 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008615 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008616 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008617 pw.println(" all: dump all activities");
8618 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008619 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008620 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8621 pw.println(" a partial substring in a component name, a");
8622 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008623 pw.println(" -a: include all available server state.");
8624 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008625 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008626 } else {
8627 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008628 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008629 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008630
8631 long origId = Binder.clearCallingIdentity();
8632 boolean more = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008633 // Is the caller requesting to dump a particular piece of data?
8634 if (opti < args.length) {
8635 String cmd = args[opti];
8636 opti++;
8637 if ("activities".equals(cmd) || "a".equals(cmd)) {
8638 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008639 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008640 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008641 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008642 String[] newArgs;
8643 String name;
8644 if (opti >= args.length) {
8645 name = null;
8646 newArgs = EMPTY_STRING_ARRAY;
8647 } else {
8648 name = args[opti];
8649 opti++;
8650 newArgs = new String[args.length - opti];
8651 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8652 args.length - opti);
8653 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008654 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008655 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008656 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008657 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008658 String[] newArgs;
8659 String name;
8660 if (opti >= args.length) {
8661 name = null;
8662 newArgs = EMPTY_STRING_ARRAY;
8663 } else {
8664 name = args[opti];
8665 opti++;
8666 newArgs = new String[args.length - opti];
8667 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8668 args.length - opti);
8669 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008670 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008671 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008672 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008673 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008674 String[] newArgs;
8675 String name;
8676 if (opti >= args.length) {
8677 name = null;
8678 newArgs = EMPTY_STRING_ARRAY;
8679 } else {
8680 name = args[opti];
8681 opti++;
8682 newArgs = new String[args.length - opti];
8683 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8684 args.length - opti);
8685 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008686 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008687 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008688 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008689 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8690 synchronized (this) {
8691 dumpOomLocked(fd, pw, args, opti, true);
8692 }
Marco Nelissen18cb2872011-11-15 11:19:53 -08008693 } else if ("provider".equals(cmd)) {
8694 String[] newArgs;
8695 String name;
8696 if (opti >= args.length) {
8697 name = null;
8698 newArgs = EMPTY_STRING_ARRAY;
8699 } else {
8700 name = args[opti];
8701 opti++;
8702 newArgs = new String[args.length - opti];
8703 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8704 }
8705 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8706 pw.println("No providers match: " + name);
8707 pw.println("Use -h for help.");
8708 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008709 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8710 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008711 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008712 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008713 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008714 String[] newArgs;
8715 String name;
8716 if (opti >= args.length) {
8717 name = null;
8718 newArgs = EMPTY_STRING_ARRAY;
8719 } else {
8720 name = args[opti];
8721 opti++;
8722 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008723 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8724 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008725 }
8726 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
8727 pw.println("No services match: " + name);
8728 pw.println("Use -h for help.");
8729 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008730 } else if ("package".equals(cmd)) {
8731 String[] newArgs;
8732 if (opti >= args.length) {
8733 pw.println("package: no package name specified");
8734 pw.println("Use -h for help.");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008735 } else {
8736 dumpPackage = args[opti];
8737 opti++;
8738 newArgs = new String[args.length - opti];
8739 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8740 args.length - opti);
8741 args = newArgs;
8742 opti = 0;
Amith Yamasani7463ada2012-04-11 15:02:39 -07008743 more = true;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008744 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008745 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8746 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008747 dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008748 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008749 } else {
8750 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008751 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8752 pw.println("Bad activity command, or no activities match: " + cmd);
8753 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008754 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008755 }
8756 if (!more) {
8757 Binder.restoreCallingIdentity(origId);
Dianne Hackborn30d71892010-12-11 10:37:55 -08008758 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008759 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008760 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008761
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008762 // No piece of data specified, dump everything.
8763 synchronized (this) {
8764 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008765 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008766 if (needSep) {
8767 pw.println(" ");
8768 }
8769 if (dumpAll) {
8770 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008771 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008772 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008773 if (needSep) {
8774 pw.println(" ");
8775 }
8776 if (dumpAll) {
8777 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008778 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008779 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008780 if (needSep) {
8781 pw.println(" ");
8782 }
8783 if (dumpAll) {
8784 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008785 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008786 needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008787 if (needSep) {
8788 pw.println(" ");
8789 }
8790 if (dumpAll) {
8791 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008792 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008793 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008794 if (needSep) {
8795 pw.println(" ");
8796 }
8797 if (dumpAll) {
8798 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008799 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008800 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008801 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008802 Binder.restoreCallingIdentity(origId);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008803 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008804
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008805 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008806 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008807 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8808 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008809 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8810 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008811 pw.println(" ");
8812 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008813 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8814 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008815 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008816 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008817 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008818 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008819 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008820 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008821 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008822 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008823 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008824 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008825 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008826 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008827 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8828 pw.println(" ");
8829 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008830 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008831 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008832 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008833 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008834 pw.println(" ");
8835 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008836 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008837 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008839
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008840 pw.println(" ");
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08008841 if (mMainStack.mPausingActivity != null) {
8842 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008843 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008844 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008845 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008846 if (dumpAll) {
8847 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8848 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008849 pw.println(" mDismissKeyguardOnNextActivity: "
8850 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008851 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008852
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008853 if (mRecentTasks.size() > 0) {
8854 pw.println();
8855 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008856
8857 final int N = mRecentTasks.size();
8858 for (int i=0; i<N; i++) {
8859 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008860 if (dumpPackage != null) {
8861 if (tr.realActivity == null ||
8862 !dumpPackage.equals(tr.realActivity)) {
8863 continue;
8864 }
8865 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008866 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8867 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008868 if (dumpAll) {
8869 mRecentTasks.get(i).dump(pw, " ");
8870 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008871 }
8872 }
8873
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008874 if (dumpAll) {
8875 pw.println(" ");
8876 pw.println(" mCurTask: " + mCurTask);
8877 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008878
8879 return true;
8880 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008881
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008882 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008883 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008884 boolean needSep = false;
8885 int numPers = 0;
8886
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008887 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8888
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008889 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008890 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8891 final int NA = procs.size();
8892 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008893 ProcessRecord r = procs.valueAt(ia);
8894 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8895 continue;
8896 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008897 if (!needSep) {
8898 pw.println(" All known processes:");
8899 needSep = true;
8900 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008901 pw.print(r.persistent ? " *PERS*" : " *APP*");
8902 pw.print(" UID "); pw.print(procs.keyAt(ia));
8903 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008904 r.dump(pw, " ");
8905 if (r.persistent) {
8906 numPers++;
8907 }
8908 }
8909 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008910 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008911
8912 if (mIsolatedProcesses.size() > 0) {
8913 if (needSep) pw.println(" ");
8914 needSep = true;
8915 pw.println(" Isolated process list (sorted by uid):");
8916 for (int i=0; i<mIsolatedProcesses.size(); i++) {
8917 ProcessRecord r = mIsolatedProcesses.valueAt(i);
8918 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8919 continue;
8920 }
8921 pw.println(String.format("%sIsolated #%2d: %s",
8922 " ", i, r.toString()));
8923 }
8924 }
8925
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008926 if (mLruProcesses.size() > 0) {
8927 if (needSep) pw.println(" ");
8928 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008929 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008930 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008931 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008932 needSep = true;
8933 }
8934
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008935 if (dumpAll) {
8936 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008937 boolean printed = false;
8938 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8939 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8940 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8941 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008942 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008943 if (!printed) {
8944 if (needSep) pw.println(" ");
8945 needSep = true;
8946 pw.println(" PID mappings:");
8947 printed = true;
8948 }
8949 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
8950 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008951 }
8952 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008953 }
8954
8955 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008956 synchronized (mPidsSelfLocked) {
8957 boolean printed = false;
8958 for (int i=0; i<mForegroundProcesses.size(); i++) {
8959 ProcessRecord r = mPidsSelfLocked.get(
8960 mForegroundProcesses.valueAt(i).pid);
8961 if (dumpPackage != null && (r == null
8962 || !dumpPackage.equals(r.info.packageName))) {
8963 continue;
8964 }
8965 if (!printed) {
8966 if (needSep) pw.println(" ");
8967 needSep = true;
8968 pw.println(" Foreground Processes:");
8969 printed = true;
8970 }
8971 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
8972 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
8973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008974 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008975 }
8976
8977 if (mPersistentStartingProcesses.size() > 0) {
8978 if (needSep) pw.println(" ");
8979 needSep = true;
8980 pw.println(" Persisent processes that are starting:");
8981 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008982 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008983 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008984
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008985 if (mRemovedProcesses.size() > 0) {
8986 if (needSep) pw.println(" ");
8987 needSep = true;
8988 pw.println(" Processes that are being removed:");
8989 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008990 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008991 }
8992
8993 if (mProcessesOnHold.size() > 0) {
8994 if (needSep) pw.println(" ");
8995 needSep = true;
8996 pw.println(" Processes that are on old until the system is ready:");
8997 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008998 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008999 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009000
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009001 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009002
9003 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009004 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009005 long now = SystemClock.uptimeMillis();
9006 for (Map.Entry<String, SparseArray<Long>> procs
9007 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009008 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009009 SparseArray<Long> uids = procs.getValue();
9010 final int N = uids.size();
9011 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009012 int puid = uids.keyAt(i);
9013 ProcessRecord r = mProcessNames.get(pname, puid);
9014 if (dumpPackage != null && (r == null
9015 || !dumpPackage.equals(r.info.packageName))) {
9016 continue;
9017 }
9018 if (!printed) {
9019 if (needSep) pw.println(" ");
9020 needSep = true;
9021 pw.println(" Time since processes crashed:");
9022 printed = true;
9023 }
9024 pw.print(" Process "); pw.print(pname);
9025 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009026 pw.print(": last crashed ");
Dianne Hackborn27ff9132012-03-06 14:57:58 -08009027 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9028 pw.println(" ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009029 }
9030 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009031 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009032
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009033 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009034 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009035 for (Map.Entry<String, SparseArray<Long>> procs
9036 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009037 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009038 SparseArray<Long> uids = procs.getValue();
9039 final int N = uids.size();
9040 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009041 int puid = uids.keyAt(i);
9042 ProcessRecord r = mProcessNames.get(pname, puid);
9043 if (dumpPackage != null && (r == null
9044 || !dumpPackage.equals(r.info.packageName))) {
9045 continue;
9046 }
9047 if (!printed) {
9048 if (needSep) pw.println(" ");
9049 needSep = true;
9050 pw.println(" Bad processes:");
9051 }
9052 pw.print(" Bad process "); pw.print(pname);
9053 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009054 pw.print(": crashed at time ");
9055 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009056 }
9057 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009059
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009060 pw.println();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009061 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009062 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08009063 if (dumpAll) {
9064 StringBuilder sb = new StringBuilder(128);
9065 sb.append(" mPreviousProcessVisibleTime: ");
9066 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9067 pw.println(sb);
9068 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07009069 if (mHeavyWeightProcess != null) {
9070 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9071 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009072 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009073 if (dumpAll) {
9074 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07009075 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009076 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009077 for (Map.Entry<String, Integer> entry
9078 : mCompatModePackages.getPackages().entrySet()) {
9079 String pkg = entry.getKey();
9080 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009081 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9082 continue;
9083 }
9084 if (!printed) {
9085 pw.println(" mScreenCompatPackages:");
9086 printed = true;
9087 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009088 pw.print(" "); pw.print(pkg); pw.print(": ");
9089 pw.print(mode); pw.println();
9090 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07009091 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009092 }
Dianne Hackbornff5b1582012-04-12 17:24:07 -07009093 if (mSleeping || mWentToSleep || mLockScreenShown) {
9094 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9095 + " mLockScreenShown " + mLockScreenShown);
9096 }
9097 if (mShuttingDown) {
9098 pw.println(" mShuttingDown=" + mShuttingDown);
9099 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009100 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9101 || mOrigWaitForDebugger) {
9102 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9103 + " mDebugTransient=" + mDebugTransient
9104 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9105 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08009106 if (mOpenGlTraceApp != null) {
9107 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
9108 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07009109 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9110 || mProfileFd != null) {
9111 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9112 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9113 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9114 + mAutoStopProfiler);
9115 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009116 if (mAlwaysFinishActivities || mController != null) {
9117 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9118 + " mController=" + mController);
9119 }
9120 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009121 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009122 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009123 + " mProcessesReady=" + mProcessesReady
9124 + " mSystemReady=" + mSystemReady);
9125 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009126 + " mBooted=" + mBooted
9127 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009128 pw.print(" mLastPowerCheckRealtime=");
9129 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9130 pw.println("");
9131 pw.print(" mLastPowerCheckUptime=");
9132 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9133 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009134 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9135 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07009136 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009137 pw.println(" mNumServiceProcs=" + mNumServiceProcs
9138 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009139 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009140
9141 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009142 }
9143
Dianne Hackborn287952c2010-09-22 22:34:31 -07009144 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009145 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009146 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009147 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009148 long now = SystemClock.uptimeMillis();
9149 for (int i=0; i<mProcessesToGc.size(); i++) {
9150 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009151 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9152 continue;
9153 }
9154 if (!printed) {
9155 if (needSep) pw.println(" ");
9156 needSep = true;
9157 pw.println(" Processes that are waiting to GC:");
9158 printed = true;
9159 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009160 pw.print(" Process "); pw.println(proc);
9161 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9162 pw.print(", last gced=");
9163 pw.print(now-proc.lastRequestedGc);
9164 pw.print(" ms ago, last lowMem=");
9165 pw.print(now-proc.lastLowMemory);
9166 pw.println(" ms ago");
9167
9168 }
9169 }
9170 return needSep;
9171 }
9172
9173 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9174 int opti, boolean dumpAll) {
9175 boolean needSep = false;
9176
9177 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009178 if (needSep) pw.println(" ");
9179 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009180 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07009181 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009182 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009183 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9184 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9185 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9186 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9187 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009188 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009189 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009190 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009191 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009192 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009193 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009194
9195 if (needSep) pw.println(" ");
9196 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009197 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07009198 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009199 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009200 needSep = true;
9201 }
9202
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009203 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009204
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009205 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07009206 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009207 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009208 if (mHeavyWeightProcess != null) {
9209 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9210 }
9211
9212 return true;
9213 }
9214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009215 /**
9216 * There are three ways to call this:
9217 * - no service specified: dump all the services
9218 * - a flattened component name that matched an existing service was specified as the
9219 * first arg: dump that one service
9220 * - the first arg isn't the flattened component name of an existing service:
9221 * dump all services whose component contains the first arg as a substring
9222 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009223 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9224 int opti, boolean dumpAll) {
9225 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009226
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009227 if ("all".equals(name)) {
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009228 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009229 try {
9230 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9231 for (UserInfo user : users) {
9232 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9233 services.add(r1);
9234 }
9235 }
9236 } catch (RemoteException re) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009237 }
9238 }
9239 } else {
9240 ComponentName componentName = name != null
9241 ? ComponentName.unflattenFromString(name) : null;
9242 int objectId = 0;
9243 if (componentName == null) {
9244 // Not a '/' separated full component name; maybe an object ID?
9245 try {
9246 objectId = Integer.parseInt(name, 16);
9247 name = null;
9248 componentName = null;
9249 } catch (RuntimeException e) {
9250 }
9251 }
9252
9253 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -07009254 try {
9255 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9256 for (UserInfo user : users) {
9257 for (ServiceRecord r1 : mServiceMap.getAllServices(user.id)) {
9258 if (componentName != null) {
9259 if (r1.name.equals(componentName)) {
9260 services.add(r1);
9261 }
9262 } else if (name != null) {
9263 if (r1.name.flattenToString().contains(name)) {
9264 services.add(r1);
9265 }
9266 } else if (System.identityHashCode(r1) == objectId) {
9267 services.add(r1);
9268 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009269 }
Dianne Hackborn14bfa392010-07-24 19:58:06 -07009270 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009271 } catch (RemoteException re) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009272 }
9273 }
9274 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009275
9276 if (services.size() <= 0) {
9277 return false;
9278 }
9279
9280 boolean needSep = false;
9281 for (int i=0; i<services.size(); i++) {
9282 if (needSep) {
9283 pw.println();
9284 }
9285 needSep = true;
9286 dumpService("", fd, pw, services.get(i), args, dumpAll);
9287 }
9288 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009289 }
9290
9291 /**
9292 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
9293 * there is a thread associated with the service.
9294 */
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009295 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
9296 final ServiceRecord r, String[] args, boolean dumpAll) {
9297 String innerPrefix = prefix + " ";
9298 synchronized (this) {
9299 pw.print(prefix); pw.print("SERVICE ");
9300 pw.print(r.shortName); pw.print(" ");
9301 pw.print(Integer.toHexString(System.identityHashCode(r)));
9302 pw.print(" pid=");
9303 if (r.app != null) pw.println(r.app.pid);
9304 else pw.println("(not running)");
9305 if (dumpAll) {
9306 r.dump(pw, innerPrefix);
9307 }
9308 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009309 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009310 pw.print(prefix); pw.println(" Client:");
9311 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009312 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009313 TransferPipe tp = new TransferPipe();
9314 try {
9315 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
9316 tp.setBufferPrefix(prefix + " ");
9317 tp.go(fd);
9318 } finally {
9319 tp.kill();
9320 }
9321 } catch (IOException e) {
9322 pw.println(prefix + " Failure while dumping the service: " + e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009323 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009324 pw.println(prefix + " Got a RemoteException while dumping the service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009325 }
9326 }
9327 }
9328
Marco Nelissen18cb2872011-11-15 11:19:53 -08009329 /**
9330 * There are three ways to call this:
9331 * - no provider specified: dump all the providers
9332 * - a flattened component name that matched an existing provider was specified as the
9333 * first arg: dump that one provider
9334 * - the first arg isn't the flattened component name of an existing provider:
9335 * dump all providers whose component contains the first arg as a substring
9336 */
9337 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9338 int opti, boolean dumpAll) {
Marco Nelissende7408c2012-02-08 14:57:38 -08009339 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
Marco Nelissen18cb2872011-11-15 11:19:53 -08009340 }
9341
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009342 static class ItemMatcher {
9343 ArrayList<ComponentName> components;
9344 ArrayList<String> strings;
9345 ArrayList<Integer> objects;
9346 boolean all;
9347
9348 ItemMatcher() {
9349 all = true;
9350 }
9351
9352 void build(String name) {
9353 ComponentName componentName = ComponentName.unflattenFromString(name);
9354 if (componentName != null) {
9355 if (components == null) {
9356 components = new ArrayList<ComponentName>();
9357 }
9358 components.add(componentName);
9359 all = false;
9360 } else {
9361 int objectId = 0;
9362 // Not a '/' separated full component name; maybe an object ID?
9363 try {
9364 objectId = Integer.parseInt(name, 16);
9365 if (objects == null) {
9366 objects = new ArrayList<Integer>();
9367 }
9368 objects.add(objectId);
9369 all = false;
9370 } catch (RuntimeException e) {
9371 // Not an integer; just do string match.
9372 if (strings == null) {
9373 strings = new ArrayList<String>();
9374 }
9375 strings.add(name);
9376 all = false;
9377 }
9378 }
9379 }
9380
9381 int build(String[] args, int opti) {
9382 for (; opti<args.length; opti++) {
9383 String name = args[opti];
9384 if ("--".equals(name)) {
9385 return opti+1;
9386 }
9387 build(name);
9388 }
9389 return opti;
9390 }
9391
9392 boolean match(Object object, ComponentName comp) {
9393 if (all) {
9394 return true;
9395 }
9396 if (components != null) {
9397 for (int i=0; i<components.size(); i++) {
9398 if (components.get(i).equals(comp)) {
9399 return true;
9400 }
9401 }
9402 }
9403 if (objects != null) {
9404 for (int i=0; i<objects.size(); i++) {
9405 if (System.identityHashCode(object) == objects.get(i)) {
9406 return true;
9407 }
9408 }
9409 }
9410 if (strings != null) {
9411 String flat = comp.flattenToString();
9412 for (int i=0; i<strings.size(); i++) {
9413 if (flat.contains(strings.get(i))) {
9414 return true;
9415 }
9416 }
9417 }
9418 return false;
9419 }
9420 }
9421
Dianne Hackborn625ac272010-09-17 18:29:22 -07009422 /**
9423 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009424 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07009425 * - the cmd arg isn't the flattened component name of an existing activity:
9426 * dump all activity whose component contains the cmd as a substring
9427 * - A hex number of the ActivityRecord object instance.
9428 */
9429 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9430 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009431 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009432
9433 if ("all".equals(name)) {
9434 synchronized (this) {
9435 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009436 activities.add(r1);
9437 }
9438 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07009439 } else if ("top".equals(name)) {
9440 synchronized (this) {
9441 final int N = mMainStack.mHistory.size();
9442 if (N > 0) {
9443 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9444 }
9445 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009446 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009447 ItemMatcher matcher = new ItemMatcher();
9448 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009449
9450 synchronized (this) {
9451 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009452 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009453 activities.add(r1);
9454 }
9455 }
9456 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009457 }
9458
9459 if (activities.size() <= 0) {
9460 return false;
9461 }
9462
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009463 String[] newArgs = new String[args.length - opti];
9464 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9465
Dianne Hackborn30d71892010-12-11 10:37:55 -08009466 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009467 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08009468 for (int i=activities.size()-1; i>=0; i--) {
9469 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009470 if (needSep) {
9471 pw.println();
9472 }
9473 needSep = true;
9474 synchronized (this) {
9475 if (lastTask != r.task) {
9476 lastTask = r.task;
9477 pw.print("TASK "); pw.print(lastTask.affinity);
9478 pw.print(" id="); pw.println(lastTask.taskId);
9479 if (dumpAll) {
9480 lastTask.dump(pw, " ");
9481 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009482 }
9483 }
9484 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009485 }
9486 return true;
9487 }
9488
9489 /**
9490 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9491 * there is a thread associated with the activity.
9492 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08009493 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009494 final ActivityRecord r, String[] args, boolean dumpAll) {
9495 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08009496 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009497 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9498 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9499 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08009500 if (r.app != null) pw.println(r.app.pid);
9501 else pw.println("(not running)");
9502 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009503 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009504 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009505 }
9506 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009507 // flush anything that is already in the PrintWriter since the thread is going
9508 // to write to the file descriptor directly
9509 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07009510 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009511 TransferPipe tp = new TransferPipe();
9512 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009513 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9514 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009515 tp.go(fd);
9516 } finally {
9517 tp.kill();
9518 }
9519 } catch (IOException e) {
9520 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009521 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009522 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009523 }
9524 }
9525 }
9526
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009527 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009528 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009529 boolean needSep = false;
9530
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009531 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009532 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009533 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009534 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009535 Iterator it = mRegisteredReceivers.values().iterator();
9536 while (it.hasNext()) {
9537 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009538 if (dumpPackage != null && (r.app == null ||
9539 !dumpPackage.equals(r.app.info.packageName))) {
9540 continue;
9541 }
9542 if (!printed) {
9543 pw.println(" Registered Receivers:");
9544 needSep = true;
9545 printed = true;
9546 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009547 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009548 r.dump(pw, " ");
9549 }
9550 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009551
9552 if (mReceiverResolver.dump(pw, needSep ?
9553 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9554 " ", dumpPackage, false)) {
9555 needSep = true;
9556 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009557 }
Christopher Tatef46723b2012-01-26 14:19:24 -08009558
9559 for (BroadcastQueue q : mBroadcastQueues) {
9560 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009562
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009563 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009564
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009565 if (mStickyBroadcasts != null && dumpPackage == null) {
9566 if (needSep) {
9567 pw.println();
9568 }
9569 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009570 pw.println(" Sticky broadcasts:");
9571 StringBuilder sb = new StringBuilder(128);
9572 for (Map.Entry<String, ArrayList<Intent>> ent
9573 : mStickyBroadcasts.entrySet()) {
9574 pw.print(" * Sticky action "); pw.print(ent.getKey());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009575 if (dumpAll) {
9576 pw.println(":");
9577 ArrayList<Intent> intents = ent.getValue();
9578 final int N = intents.size();
9579 for (int i=0; i<N; i++) {
9580 sb.setLength(0);
9581 sb.append(" Intent: ");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08009582 intents.get(i).toShortString(sb, false, true, false, false);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009583 pw.println(sb.toString());
9584 Bundle bundle = intents.get(i).getExtras();
9585 if (bundle != null) {
9586 pw.print(" ");
9587 pw.println(bundle.toString());
9588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009589 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009590 } else {
9591 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009592 }
9593 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009594 needSep = true;
9595 }
9596
9597 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009598 pw.println();
Christopher Tatef46723b2012-01-26 14:19:24 -08009599 for (BroadcastQueue queue : mBroadcastQueues) {
9600 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
9601 + queue.mBroadcastsScheduled);
9602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009603 pw.println(" mHandler:");
9604 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009605 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009606 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009607
9608 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009609 }
9610
Marco Nelissen18cb2872011-11-15 11:19:53 -08009611 /**
9612 * Prints a list of ServiceRecords (dumpsys activity services)
9613 */
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009614 boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009615 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009616 boolean needSep = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009617
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009618 ItemMatcher matcher = new ItemMatcher();
9619 matcher.build(args, opti);
9620
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009621 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
Amith Yamasani742a6712011-05-04 14:49:28 -07009622 try {
9623 List<UserInfo> users = AppGlobals.getPackageManager().getUsers();
9624 for (UserInfo user : users) {
9625 if (mServiceMap.getAllServices(user.id).size() > 0) {
9626 boolean printed = false;
9627 long nowReal = SystemClock.elapsedRealtime();
9628 Iterator<ServiceRecord> it = mServiceMap.getAllServices(
9629 user.id).iterator();
9630 needSep = false;
9631 while (it.hasNext()) {
9632 ServiceRecord r = it.next();
9633 if (!matcher.match(r, r.name)) {
9634 continue;
9635 }
9636 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9637 continue;
9638 }
9639 if (!printed) {
9640 pw.println(" Active services:");
9641 printed = true;
9642 }
9643 if (needSep) {
9644 pw.println();
9645 }
9646 pw.print(" * ");
9647 pw.println(r);
9648 if (dumpAll) {
9649 r.dump(pw, " ");
9650 needSep = true;
9651 } else {
9652 pw.print(" app=");
9653 pw.println(r.app);
9654 pw.print(" created=");
9655 TimeUtils.formatDuration(r.createTime, nowReal, pw);
9656 pw.print(" started=");
9657 pw.print(r.startRequested);
9658 pw.print(" connections=");
9659 pw.println(r.connections.size());
9660 if (r.connections.size() > 0) {
9661 pw.println(" Connections:");
9662 for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
9663 for (int i = 0; i < clist.size(); i++) {
9664 ConnectionRecord conn = clist.get(i);
9665 pw.print(" ");
9666 pw.print(conn.binding.intent.intent.getIntent()
Dianne Hackborn21c241e2012-03-08 13:57:23 -08009667 .toShortString(false, false, false, false));
Amith Yamasani742a6712011-05-04 14:49:28 -07009668 pw.print(" -> ");
9669 ProcessRecord proc = conn.binding.client;
9670 pw.println(proc != null ? proc.toShortString() : "null");
9671 }
9672 }
Dianne Hackborn8ec8d412011-11-14 18:27:24 -08009673 }
9674 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009675 if (dumpClient && r.app != null && r.app.thread != null) {
9676 pw.println(" Client:");
9677 pw.flush();
9678 try {
9679 TransferPipe tp = new TransferPipe();
9680 try {
9681 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
9682 r, args);
9683 tp.setBufferPrefix(" ");
9684 // Short timeout, since blocking here can
9685 // deadlock with the application.
9686 tp.go(fd, 2000);
9687 } finally {
9688 tp.kill();
9689 }
9690 } catch (IOException e) {
9691 pw.println(" Failure while dumping the service: " + e);
9692 } catch (RemoteException e) {
9693 pw.println(" Got a RemoteException while dumping the service");
9694 }
9695 needSep = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009696 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009697 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009698 needSep = printed;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009699 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009700 }
Amith Yamasani742a6712011-05-04 14:49:28 -07009701 } catch (RemoteException re) {
9702
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009704
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009705 if (mPendingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009706 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009707 for (int i=0; i<mPendingServices.size(); i++) {
9708 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009709 if (!matcher.match(r, r.name)) {
9710 continue;
9711 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009712 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9713 continue;
9714 }
9715 if (!printed) {
9716 if (needSep) pw.println(" ");
9717 needSep = true;
9718 pw.println(" Pending services:");
9719 printed = true;
9720 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009721 pw.print(" * Pending "); pw.println(r);
9722 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009723 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009724 needSep = true;
9725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009726
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009727 if (mRestartingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009728 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009729 for (int i=0; i<mRestartingServices.size(); i++) {
9730 ServiceRecord r = mRestartingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009731 if (!matcher.match(r, r.name)) {
9732 continue;
9733 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009734 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9735 continue;
9736 }
9737 if (!printed) {
9738 if (needSep) pw.println(" ");
9739 needSep = true;
9740 pw.println(" Restarting services:");
9741 printed = true;
9742 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009743 pw.print(" * Restarting "); pw.println(r);
9744 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009745 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009746 needSep = true;
9747 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009748
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009749 if (mStoppingServices.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009750 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009751 for (int i=0; i<mStoppingServices.size(); i++) {
9752 ServiceRecord r = mStoppingServices.get(i);
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009753 if (!matcher.match(r, r.name)) {
9754 continue;
9755 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009756 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
9757 continue;
9758 }
9759 if (!printed) {
9760 if (needSep) pw.println(" ");
9761 needSep = true;
9762 pw.println(" Stopping services:");
9763 printed = true;
9764 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009765 pw.print(" * Stopping "); pw.println(r);
9766 r.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009767 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009768 needSep = true;
9769 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009770
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009771 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009772 if (mServiceConnections.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009773 boolean printed = false;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009774 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009775 = mServiceConnections.values().iterator();
9776 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009777 ArrayList<ConnectionRecord> r = it.next();
9778 for (int i=0; i<r.size(); i++) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009779 ConnectionRecord cr = r.get(i);
9780 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
9781 continue;
9782 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009783 if (dumpPackage != null && (cr.binding.client == null
9784 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
9785 continue;
9786 }
9787 if (!printed) {
9788 if (needSep) pw.println(" ");
9789 needSep = true;
9790 pw.println(" Connection bindings to services:");
9791 printed = true;
9792 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009793 pw.print(" * "); pw.println(cr);
9794 cr.dump(pw, " ");
Dianne Hackborn43d9ac82010-08-25 15:06:25 -07009795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009796 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009797 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009798 }
9799 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009800
9801 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009802 }
9803
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009804 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009805 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07009806 boolean needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009807
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009808 ItemMatcher matcher = new ItemMatcher();
9809 matcher.build(args, opti);
9810
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009811 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
Amith Yamasani742a6712011-05-04 14:49:28 -07009812
9813 mProviderMap.dumpProvidersLocked(pw, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009814
9815 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009816 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009817 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009818 ContentProviderRecord r = mLaunchingProviders.get(i);
9819 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9820 continue;
9821 }
9822 if (!printed) {
9823 if (needSep) pw.println(" ");
9824 needSep = true;
9825 pw.println(" Launching content providers:");
9826 printed = true;
9827 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009828 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009829 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009830 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009831 }
9832
9833 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009834 if (needSep) pw.println();
9835 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009836 pw.println("Granted Uri Permissions:");
9837 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9838 int uid = mGrantedUriPermissions.keyAt(i);
9839 HashMap<Uri, UriPermission> perms
9840 = mGrantedUriPermissions.valueAt(i);
9841 pw.print(" * UID "); pw.print(uid);
9842 pw.println(" holds:");
9843 for (UriPermission perm : perms.values()) {
9844 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009845 if (dumpAll) {
9846 perm.dump(pw, " ");
9847 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009848 }
9849 }
9850 needSep = true;
9851 }
9852
9853 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009854 }
9855
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009856 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009857 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009858 boolean needSep = false;
9859
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009860 if (mIntentSenderRecords.size() > 0) {
9861 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009862 Iterator<WeakReference<PendingIntentRecord>> it
9863 = mIntentSenderRecords.values().iterator();
9864 while (it.hasNext()) {
9865 WeakReference<PendingIntentRecord> ref = it.next();
9866 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009867 if (dumpPackage != null && (rec == null
9868 || !dumpPackage.equals(rec.key.packageName))) {
9869 continue;
9870 }
9871 if (!printed) {
9872 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9873 printed = true;
9874 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009875 needSep = true;
9876 if (rec != null) {
9877 pw.print(" * "); pw.println(rec);
9878 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009879 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009880 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009881 } else {
9882 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009883 }
9884 }
9885 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009886
9887 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009888 }
9889
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009890 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009891 String prefix, String label, boolean complete, boolean brief, boolean client,
9892 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009893 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009894 boolean needNL = false;
9895 final String innerPrefix = prefix + " ";
9896 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009897 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009898 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009899 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9900 continue;
9901 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009902 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009903 if (needNL) {
9904 pw.println(" ");
9905 needNL = false;
9906 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009907 if (lastTask != r.task) {
9908 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009909 pw.print(prefix);
9910 pw.print(full ? "* " : " ");
9911 pw.println(lastTask);
9912 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009913 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009914 } else if (complete) {
9915 // Complete + brief == give a summary. Isn't that obvious?!?
9916 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009917 pw.print(prefix); pw.print(" ");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08009918 pw.println(lastTask.intent.toInsecureStringWithClip());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009919 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009921 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009922 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9923 pw.print(" #"); pw.print(i); pw.print(": ");
9924 pw.println(r);
9925 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009926 r.dump(pw, innerPrefix);
9927 } else if (complete) {
9928 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009929 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009930 if (r.app != null) {
9931 pw.print(innerPrefix); pw.println(r.app);
9932 }
9933 }
9934 if (client && r.app != null && r.app.thread != null) {
9935 // flush anything that is already in the PrintWriter since the thread is going
9936 // to write to the file descriptor directly
9937 pw.flush();
9938 try {
9939 TransferPipe tp = new TransferPipe();
9940 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009941 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9942 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009943 // Short timeout, since blocking here can
9944 // deadlock with the application.
9945 tp.go(fd, 2000);
9946 } finally {
9947 tp.kill();
9948 }
9949 } catch (IOException e) {
9950 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9951 } catch (RemoteException e) {
9952 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9953 }
9954 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 }
9957 }
9958
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009959 private static String buildOomTag(String prefix, String space, int val, int base) {
9960 if (val == base) {
9961 if (space == null) return prefix;
9962 return prefix + " ";
9963 }
9964 return prefix + "+" + Integer.toString(val-base);
9965 }
9966
9967 private static final int dumpProcessList(PrintWriter pw,
9968 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009969 String prefix, String normalLabel, String persistentLabel,
9970 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009971 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009972 final int N = list.size()-1;
9973 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009974 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009975 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9976 continue;
9977 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009978 pw.println(String.format("%s%s #%2d: %s",
9979 prefix, (r.persistent ? persistentLabel : normalLabel),
9980 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009981 if (r.persistent) {
9982 numPers++;
9983 }
9984 }
9985 return numPers;
9986 }
9987
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009988 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009989 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009990 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009991 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009992
Dianne Hackborn905577f2011-09-07 18:31:28 -07009993 ArrayList<Pair<ProcessRecord, Integer>> list
9994 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9995 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009996 ProcessRecord r = origList.get(i);
9997 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9998 continue;
9999 }
Dianne Hackborn905577f2011-09-07 18:31:28 -070010000 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10001 }
10002
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010003 if (list.size() <= 0) {
10004 return false;
10005 }
10006
Dianne Hackborn905577f2011-09-07 18:31:28 -070010007 Comparator<Pair<ProcessRecord, Integer>> comparator
10008 = new Comparator<Pair<ProcessRecord, Integer>>() {
10009 @Override
10010 public int compare(Pair<ProcessRecord, Integer> object1,
10011 Pair<ProcessRecord, Integer> object2) {
10012 if (object1.first.setAdj != object2.first.setAdj) {
10013 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10014 }
10015 if (object1.second.intValue() != object2.second.intValue()) {
10016 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10017 }
10018 return 0;
10019 }
10020 };
10021
10022 Collections.sort(list, comparator);
10023
Dianne Hackborn287952c2010-09-22 22:34:31 -070010024 final long curRealtime = SystemClock.elapsedRealtime();
10025 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10026 final long curUptime = SystemClock.uptimeMillis();
10027 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10028
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010029 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070010030 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010031 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010032 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070010033 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010034 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10035 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010036 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10037 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010038 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10039 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010040 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10041 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010042 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010043 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010044 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10045 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10046 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10047 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10048 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10049 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10050 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10051 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010052 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10053 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010054 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10055 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010056 } else {
10057 oomAdj = Integer.toString(r.setAdj);
10058 }
10059 String schedGroup;
10060 switch (r.setSchedGroup) {
10061 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10062 schedGroup = "B";
10063 break;
10064 case Process.THREAD_GROUP_DEFAULT:
10065 schedGroup = "F";
10066 break;
10067 default:
10068 schedGroup = Integer.toString(r.setSchedGroup);
10069 break;
10070 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010071 String foreground;
10072 if (r.foregroundActivities) {
10073 foreground = "A";
10074 } else if (r.foregroundServices) {
10075 foreground = "S";
10076 } else {
10077 foreground = " ";
10078 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010079 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -070010080 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010081 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10082 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -070010083 if (r.adjSource != null || r.adjTarget != null) {
10084 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010085 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070010086 if (r.adjTarget instanceof ComponentName) {
10087 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10088 } else if (r.adjTarget != null) {
10089 pw.print(r.adjTarget.toString());
10090 } else {
10091 pw.print("{null}");
10092 }
10093 pw.print("<=");
10094 if (r.adjSource instanceof ProcessRecord) {
10095 pw.print("Proc{");
10096 pw.print(((ProcessRecord)r.adjSource).toShortString());
10097 pw.println("}");
10098 } else if (r.adjSource != null) {
10099 pw.println(r.adjSource.toString());
10100 } else {
10101 pw.println("{null}");
10102 }
10103 }
10104 if (inclDetails) {
10105 pw.print(prefix);
10106 pw.print(" ");
10107 pw.print("oom: max="); pw.print(r.maxAdj);
10108 pw.print(" hidden="); pw.print(r.hiddenAdj);
10109 pw.print(" curRaw="); pw.print(r.curRawAdj);
10110 pw.print(" setRaw="); pw.print(r.setRawAdj);
10111 pw.print(" cur="); pw.print(r.curAdj);
10112 pw.print(" set="); pw.println(r.setAdj);
10113 pw.print(prefix);
10114 pw.print(" ");
10115 pw.print("keeping="); pw.print(r.keeping);
10116 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010117 pw.print(" empty="); pw.print(r.empty);
10118 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010119
10120 if (!r.keeping) {
10121 if (r.lastWakeTime != 0) {
10122 long wtime;
10123 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10124 synchronized (stats) {
10125 wtime = stats.getProcessWakeTime(r.info.uid,
10126 r.pid, curRealtime);
10127 }
10128 long timeUsed = wtime - r.lastWakeTime;
10129 pw.print(prefix);
10130 pw.print(" ");
10131 pw.print("keep awake over ");
10132 TimeUtils.formatDuration(realtimeSince, pw);
10133 pw.print(" used ");
10134 TimeUtils.formatDuration(timeUsed, pw);
10135 pw.print(" (");
10136 pw.print((timeUsed*100)/realtimeSince);
10137 pw.println("%)");
10138 }
10139 if (r.lastCpuTime != 0) {
10140 long timeUsed = r.curCpuTime - r.lastCpuTime;
10141 pw.print(prefix);
10142 pw.print(" ");
10143 pw.print("run cpu over ");
10144 TimeUtils.formatDuration(uptimeSince, pw);
10145 pw.print(" used ");
10146 TimeUtils.formatDuration(timeUsed, pw);
10147 pw.print(" (");
10148 pw.print((timeUsed*100)/uptimeSince);
10149 pw.println("%)");
10150 }
10151 }
10152 }
10153 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010154 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010155 }
10156
Dianne Hackbornb437e092011-08-05 17:50:29 -070010157 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010158 ArrayList<ProcessRecord> procs;
10159 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010160 if (args != null && args.length > start
10161 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010162 procs = new ArrayList<ProcessRecord>();
10163 int pid = -1;
10164 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010165 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010166 } catch (NumberFormatException e) {
10167
10168 }
10169 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10170 ProcessRecord proc = mLruProcesses.get(i);
10171 if (proc.pid == pid) {
10172 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010173 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010174 procs.add(proc);
10175 }
10176 }
10177 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010178 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010179 return null;
10180 }
10181 } else {
10182 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10183 }
10184 }
10185 return procs;
10186 }
10187
10188 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10189 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010190 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010191 if (procs == null) {
10192 return;
10193 }
10194
10195 long uptime = SystemClock.uptimeMillis();
10196 long realtime = SystemClock.elapsedRealtime();
10197 pw.println("Applications Graphics Acceleration Info:");
10198 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10199
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010200 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10201 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010202 if (r.thread != null) {
10203 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10204 pw.flush();
10205 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010206 TransferPipe tp = new TransferPipe();
10207 try {
10208 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10209 tp.go(fd);
10210 } finally {
10211 tp.kill();
10212 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010213 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010214 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010215 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -070010216 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010217 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010218 pw.flush();
10219 }
10220 }
10221 }
Chet Haase9c1e23b2011-03-24 10:51:31 -070010222 }
10223
Jeff Brown6754ba22011-12-14 20:20:01 -080010224 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10225 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10226 if (procs == null) {
10227 return;
10228 }
10229
10230 pw.println("Applications Database Info:");
10231
10232 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10233 ProcessRecord r = procs.get(i);
10234 if (r.thread != null) {
10235 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10236 pw.flush();
10237 try {
10238 TransferPipe tp = new TransferPipe();
10239 try {
10240 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10241 tp.go(fd);
10242 } finally {
10243 tp.kill();
10244 }
10245 } catch (IOException e) {
10246 pw.println("Failure while dumping the app: " + r);
10247 pw.flush();
10248 } catch (RemoteException e) {
10249 pw.println("Got a RemoteException while dumping the app " + r);
10250 pw.flush();
10251 }
10252 }
10253 }
10254 }
10255
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010256 final static class MemItem {
10257 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010258 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010259 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010260 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010261 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010262
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010263 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010264 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010265 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010266 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010267 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010268 }
10269 }
10270
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010271 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -070010272 boolean sort) {
10273 if (sort) {
10274 Collections.sort(items, new Comparator<MemItem>() {
10275 @Override
10276 public int compare(MemItem lhs, MemItem rhs) {
10277 if (lhs.pss < rhs.pss) {
10278 return 1;
10279 } else if (lhs.pss > rhs.pss) {
10280 return -1;
10281 }
10282 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010283 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010284 });
10285 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010286
10287 for (int i=0; i<items.size(); i++) {
10288 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010289 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010290 if (mi.subitems != null) {
10291 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10292 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010293 }
10294 }
10295
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010296 // These are in KB.
10297 static final long[] DUMP_MEM_BUCKETS = new long[] {
10298 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10299 120*1024, 160*1024, 200*1024,
10300 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10301 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10302 };
10303
Dianne Hackborn672342c2011-11-29 11:29:02 -080010304 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10305 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010306 int start = label.lastIndexOf('.');
10307 if (start >= 0) start++;
10308 else start = 0;
10309 int end = label.length();
10310 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10311 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10312 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10313 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010314 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010315 out.append(label, start, end);
10316 return;
10317 }
10318 }
10319 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010320 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010321 out.append(label, start, end);
10322 }
10323
10324 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10325 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10326 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10327 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10328 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10329 };
10330 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10331 "System", "Persistent", "Foreground",
10332 "Visible", "Perceptible", "Heavy Weight",
10333 "Backup", "A Services", "Home", "Previous",
10334 "B Services", "Background"
10335 };
10336
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010337 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010338 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -080010339 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010340 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010341 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010342
10343 int opti = 0;
10344 while (opti < args.length) {
10345 String opt = args[opti];
10346 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10347 break;
10348 }
10349 opti++;
10350 if ("-a".equals(opt)) {
10351 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010352 } else if ("--oom".equals(opt)) {
10353 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010354 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010355 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010356 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010357 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010358 pw.println("If [process] is specified it can be the name or ");
10359 pw.println("pid of a specific process to dump.");
10360 return;
10361 } else {
10362 pw.println("Unknown argument: " + opt + "; use -h for help");
10363 }
10364 }
10365
10366 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010367 if (procs == null) {
10368 return;
10369 }
10370
Dianne Hackborn6447ca32009-04-07 19:50:08 -070010371 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010372 long uptime = SystemClock.uptimeMillis();
10373 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -070010374
10375 if (procs.size() == 1 || isCheckinRequest) {
10376 dumpAll = true;
10377 }
10378
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010379 if (isCheckinRequest) {
10380 // short checkin version
10381 pw.println(uptime + "," + realtime);
10382 pw.flush();
10383 } else {
10384 pw.println("Applications Memory Usage (kB):");
10385 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10386 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010387
Dianne Hackbornb437e092011-08-05 17:50:29 -070010388 String[] innerArgs = new String[args.length-opti];
10389 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10390
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010391 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10392 long nativePss=0, dalvikPss=0, otherPss=0;
10393 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10394
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010395 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10396 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10397 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -070010398
10399 long totalPss = 0;
10400
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010401 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10402 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010403 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010404 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010405 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10406 pw.flush();
10407 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010408 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010409 if (dumpAll) {
10410 try {
10411 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10412 } catch (RemoteException e) {
10413 if (!isCheckinRequest) {
10414 pw.println("Got RemoteException!");
10415 pw.flush();
10416 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010417 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010418 } else {
10419 mi = new Debug.MemoryInfo();
10420 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010421 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010422
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010423 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010424 long myTotalPss = mi.getTotalPss();
10425 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010426 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010427 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010428 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010429
10430 nativePss += mi.nativePss;
10431 dalvikPss += mi.dalvikPss;
10432 otherPss += mi.otherPss;
10433 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10434 long mem = mi.getOtherPss(j);
10435 miscPss[j] += mem;
10436 otherPss -= mem;
10437 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010438
10439 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010440 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10441 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010442 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010443 if (oomProcs[oomIndex] == null) {
10444 oomProcs[oomIndex] = new ArrayList<MemItem>();
10445 }
10446 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010447 break;
10448 }
10449 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010450 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010451 }
10452 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010453
10454 if (!isCheckinRequest && procs.size() > 1) {
10455 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10456
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010457 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10458 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10459 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010460 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010461 String label = Debug.MemoryInfo.getOtherLabel(j);
10462 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010463 }
10464
Dianne Hackbornb437e092011-08-05 17:50:29 -070010465 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10466 for (int j=0; j<oomPss.length; j++) {
10467 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010468 String label = DUMP_MEM_OOM_LABEL[j];
10469 MemItem item = new MemItem(label, label, oomPss[j],
10470 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010471 item.subitems = oomProcs[j];
10472 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010473 }
10474 }
10475
Dianne Hackborn672342c2011-11-29 11:29:02 -080010476 if (outTag != null || outStack != null) {
10477 if (outTag != null) {
10478 appendMemBucket(outTag, totalPss, "total", false);
10479 }
10480 if (outStack != null) {
10481 appendMemBucket(outStack, totalPss, "total", true);
10482 }
10483 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010484 for (int i=0; i<oomMems.size(); i++) {
10485 MemItem miCat = oomMems.get(i);
10486 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10487 continue;
10488 }
10489 if (miCat.id < ProcessList.SERVICE_ADJ
10490 || miCat.id == ProcessList.HOME_APP_ADJ
10491 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010492 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10493 outTag.append(" / ");
10494 }
10495 if (outStack != null) {
10496 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10497 if (firstLine) {
10498 outStack.append(":");
10499 firstLine = false;
10500 }
10501 outStack.append("\n\t at ");
10502 } else {
10503 outStack.append("$");
10504 }
10505 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010506 for (int j=0; j<miCat.subitems.size(); j++) {
10507 MemItem mi = miCat.subitems.get(j);
10508 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010509 if (outTag != null) {
10510 outTag.append(" ");
10511 }
10512 if (outStack != null) {
10513 outStack.append("$");
10514 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010515 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010516 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10517 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10518 }
10519 if (outStack != null) {
10520 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10521 }
10522 }
10523 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10524 outStack.append("(");
10525 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10526 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10527 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10528 outStack.append(":");
10529 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10530 }
10531 }
10532 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010533 }
10534 }
10535 }
10536 }
10537
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010538 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010539 pw.println();
10540 pw.println("Total PSS by process:");
10541 dumpMemItems(pw, " ", procMems, true);
10542 pw.println();
10543 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010544 pw.println("Total PSS by OOM adjustment:");
10545 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010546 if (!oomOnly) {
10547 PrintWriter out = categoryPw != null ? categoryPw : pw;
10548 out.println();
10549 out.println("Total PSS by category:");
10550 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010551 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010552 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010553 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackbornd3e677b2012-04-05 14:58:18 -070010554 final int[] SINGLE_LONG_FORMAT = new int[] {
10555 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10556 };
10557 long[] longOut = new long[1];
10558 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10559 SINGLE_LONG_FORMAT, null, longOut, null);
10560 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10561 longOut[0] = 0;
10562 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10563 SINGLE_LONG_FORMAT, null, longOut, null);
10564 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10565 longOut[0] = 0;
10566 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10567 SINGLE_LONG_FORMAT, null, longOut, null);
10568 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10569 longOut[0] = 0;
10570 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10571 SINGLE_LONG_FORMAT, null, longOut, null);
10572 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10573 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10574 pw.print(shared); pw.println(" kB");
10575 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
10576 pw.print(voltile); pw.println(" kB volatile");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010578 }
10579
10580 /**
10581 * Searches array of arguments for the specified string
10582 * @param args array of argument strings
10583 * @param value value to search for
10584 * @return true if the value is contained in the array
10585 */
10586 private static boolean scanArgs(String[] args, String value) {
10587 if (args != null) {
10588 for (String arg : args) {
10589 if (value.equals(arg)) {
10590 return true;
10591 }
10592 }
10593 }
10594 return false;
10595 }
10596
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010597 private final void killServicesLocked(ProcessRecord app,
10598 boolean allowRestart) {
10599 // Report disconnected services.
10600 if (false) {
10601 // XXX we are letting the client link to the service for
10602 // death notifications.
10603 if (app.services.size() > 0) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010604 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010605 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010606 ServiceRecord r = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010607 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010608 Iterator<ArrayList<ConnectionRecord>> jt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010609 = r.connections.values().iterator();
10610 while (jt.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010611 ArrayList<ConnectionRecord> cl = jt.next();
10612 for (int i=0; i<cl.size(); i++) {
10613 ConnectionRecord c = cl.get(i);
10614 if (c.binding.client != app) {
10615 try {
10616 //c.conn.connected(r.className, null);
10617 } catch (Exception e) {
10618 // todo: this should be asynchronous!
10619 Slog.w(TAG, "Exception thrown disconnected servce "
10620 + r.shortName
10621 + " from app " + app.processName, e);
10622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010623 }
10624 }
10625 }
10626 }
10627 }
10628 }
10629 }
10630
10631 // Clean up any connections this application has to other services.
10632 if (app.connections.size() > 0) {
10633 Iterator<ConnectionRecord> it = app.connections.iterator();
10634 while (it.hasNext()) {
10635 ConnectionRecord r = it.next();
10636 removeConnectionLocked(r, app, null);
10637 }
10638 }
10639 app.connections.clear();
10640
10641 if (app.services.size() != 0) {
10642 // Any services running in the application need to be placed
10643 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -070010644 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010645 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010646 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010647 synchronized (sr.stats.getBatteryStats()) {
10648 sr.stats.stopLaunchedLocked();
10649 }
10650 sr.app = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010651 sr.isolatedProc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010652 sr.executeNesting = 0;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010653 if (mStoppingServices.remove(sr)) {
10654 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
10655 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010656
10657 boolean hasClients = sr.bindings.size() > 0;
10658 if (hasClients) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010659 Iterator<IntentBindRecord> bindings
10660 = sr.bindings.values().iterator();
10661 while (bindings.hasNext()) {
10662 IntentBindRecord b = bindings.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080010663 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 + ": shouldUnbind=" + b.hasBound);
10665 b.binder = null;
10666 b.requested = b.received = b.hasBound = false;
10667 }
10668 }
10669
Dianne Hackborn070783f2010-12-29 16:46:28 -080010670 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
10671 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010672 Slog.w(TAG, "Service crashed " + sr.crashCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010673 + " times, stopping: " + sr);
Doug Zongker2bec3d42009-12-04 12:52:44 -080010674 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 sr.crashCount, sr.shortName, app.pid);
10676 bringDownServiceLocked(sr, true);
10677 } else if (!allowRestart) {
10678 bringDownServiceLocked(sr, true);
10679 } else {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010680 boolean canceled = scheduleServiceRestartLocked(sr, true);
10681
10682 // Should the service remain running? Note that in the
10683 // extreme case of so many attempts to deliver a command
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010684 // that it failed we also will stop it here.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010685 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
10686 if (sr.pendingStarts.size() == 0) {
10687 sr.startRequested = false;
10688 if (!hasClients) {
10689 // Whoops, no reason to restart!
10690 bringDownServiceLocked(sr, true);
10691 }
10692 }
10693 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010694 }
10695 }
10696
10697 if (!allowRestart) {
10698 app.services.clear();
10699 }
10700 }
10701
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010702 // Make sure we have no more records on the stopping list.
10703 int i = mStoppingServices.size();
10704 while (i > 0) {
10705 i--;
10706 ServiceRecord sr = mStoppingServices.get(i);
10707 if (sr.app == app) {
10708 mStoppingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070010709 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove stopping " + sr);
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010710 }
10711 }
10712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010713 app.executingServices.clear();
10714 }
10715
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010716 private final boolean removeDyingProviderLocked(ProcessRecord proc,
10717 ContentProviderRecord cpr, boolean always) {
10718 final boolean inLaunching = mLaunchingProviders.contains(cpr);
10719
10720 if (!inLaunching || always) {
10721 synchronized (cpr) {
10722 cpr.launchingApp = null;
10723 cpr.notifyAll();
10724 }
10725 mProviderMap.removeProviderByClass(cpr.name, UserId.getUserId(cpr.uid));
10726 String names[] = cpr.info.authority.split(";");
10727 for (int j = 0; j < names.length; j++) {
10728 mProviderMap.removeProviderByName(names[j], UserId.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010729 }
10730 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010731
10732 for (int i=0; i<cpr.connections.size(); i++) {
10733 ContentProviderConnection conn = cpr.connections.get(i);
10734 if (conn.waiting) {
10735 // If this connection is waiting for the provider, then we don't
10736 // need to mess with its process unless we are always removing
10737 // or for some reason the provider is not currently launching.
10738 if (inLaunching && !always) {
10739 continue;
10740 }
10741 }
10742 ProcessRecord capp = conn.client;
10743 conn.dead = true;
10744 if (conn.stableCount > 0) {
10745 if (!capp.persistent && capp.thread != null
10746 && capp.pid != 0
10747 && capp.pid != MY_PID) {
10748 Slog.i(TAG, "Kill " + capp.processName
10749 + " (pid " + capp.pid + "): provider " + cpr.info.name
10750 + " in dying process " + (proc != null ? proc.processName : "??"));
10751 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10752 capp.processName, capp.setAdj, "dying provider "
10753 + cpr.name.toShortString());
10754 Process.killProcessQuiet(capp.pid);
10755 }
10756 } else if (capp.thread != null && conn.provider.provider != null) {
10757 try {
10758 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10759 } catch (RemoteException e) {
10760 }
10761 // In the protocol here, we don't expect the client to correctly
10762 // clean up this connection, we'll just remove it.
10763 cpr.connections.remove(i);
10764 conn.client.conProviders.remove(conn);
10765 }
10766 }
10767
10768 if (inLaunching && always) {
10769 mLaunchingProviders.remove(cpr);
10770 }
10771 return inLaunching;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772 }
10773
10774 /**
10775 * Main code for cleaning up a process when it has gone away. This is
10776 * called both as a result of the process dying, or directly when stopping
10777 * a process when running in single process mode.
10778 */
10779 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010780 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010781 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010782 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010783 }
10784
Dianne Hackborn36124872009-10-08 16:22:03 -070010785 mProcessesToGc.remove(app);
10786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010787 // Dismiss any open dialogs.
10788 if (app.crashDialog != null) {
10789 app.crashDialog.dismiss();
10790 app.crashDialog = null;
10791 }
10792 if (app.anrDialog != null) {
10793 app.anrDialog.dismiss();
10794 app.anrDialog = null;
10795 }
10796 if (app.waitDialog != null) {
10797 app.waitDialog.dismiss();
10798 app.waitDialog = null;
10799 }
10800
10801 app.crashing = false;
10802 app.notResponding = false;
10803
10804 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010805 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 app.thread = null;
10807 app.forcingToForeground = null;
10808 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010809 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010810 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010811 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010812
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010813 killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010814
10815 boolean restart = false;
10816
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010817 // Remove published content providers.
10818 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010819 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010820 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010821 ContentProviderRecord cpr = it.next();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010822
10823 final boolean always = app.bad || !allowRestart;
10824 if (removeDyingProviderLocked(app, cpr, always) || always) {
10825 // We left the provider in the launching list, need to
10826 // restart it.
10827 restart = true;
10828 }
10829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010830 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010831 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010832 }
10833 app.pubProviders.clear();
10834 }
10835
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010836 // Take care of any launching providers waiting for this process.
10837 if (checkAppInLaunchingProvidersLocked(app, false)) {
10838 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010839 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010840
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010841 // Unregister from connected content providers.
10842 if (!app.conProviders.isEmpty()) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010843 for (int i=0; i<app.conProviders.size(); i++) {
10844 ContentProviderConnection conn = app.conProviders.get(i);
10845 conn.provider.connections.remove(conn);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010846 }
10847 app.conProviders.clear();
10848 }
10849
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010850 // At this point there may be remaining entries in mLaunchingProviders
10851 // where we were the only one waiting, so they are no longer of use.
10852 // Look for these and clean up if found.
10853 // XXX Commented out for now. Trying to figure out a way to reproduce
10854 // the actual situation to identify what is actually going on.
10855 if (false) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010856 for (int i=0; i<mLaunchingProviders.size(); i++) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010857 ContentProviderRecord cpr = (ContentProviderRecord)
10858 mLaunchingProviders.get(i);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010859 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010860 synchronized (cpr) {
10861 cpr.launchingApp = null;
10862 cpr.notifyAll();
10863 }
10864 }
10865 }
10866 }
10867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010868 skipCurrentReceiverLocked(app);
10869
10870 // Unregister any receivers.
10871 if (app.receivers.size() > 0) {
10872 Iterator<ReceiverList> it = app.receivers.iterator();
10873 while (it.hasNext()) {
10874 removeReceiverLocked(it.next());
10875 }
10876 app.receivers.clear();
10877 }
10878
Christopher Tate181fafa2009-05-14 11:12:14 -070010879 // If the app is undergoing backup, tell the backup manager about it
10880 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010881 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010882 try {
10883 IBackupManager bm = IBackupManager.Stub.asInterface(
10884 ServiceManager.getService(Context.BACKUP_SERVICE));
10885 bm.agentDisconnected(app.info.packageName);
10886 } catch (RemoteException e) {
10887 // can't happen; backup manager is local
10888 }
10889 }
10890
Dianne Hackborna93c2c12012-05-31 15:29:36 -070010891 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10892 ProcessChangeItem item = mPendingProcessChanges.get(i);
10893 if (item.pid == app.pid) {
10894 mPendingProcessChanges.remove(i);
10895 mAvailProcessChanges.add(item);
10896 }
10897 }
Jeff Sharkey287bd832011-05-28 19:36:26 -070010898 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010900 // If the caller is restarting this app, then leave it in its
10901 // current lists and let the caller take care of it.
10902 if (restarting) {
10903 return;
10904 }
10905
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010906 if (!app.persistent || app.isolated) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010907 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010908 "Removing non-persistent process during cleanup: " + app);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010909 mProcessNames.remove(app.processName, app.uid);
10910 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010911 if (mHeavyWeightProcess == app) {
10912 mHeavyWeightProcess = null;
10913 mHandler.sendEmptyMessage(CANCEL_HEAVY_NOTIFICATION_MSG);
10914 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010915 } else if (!app.removed) {
10916 // This app is persistent, so we need to keep its record around.
10917 // If it is not already on the pending app list, add it there
10918 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010919 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10920 mPersistentStartingProcesses.add(app);
10921 restart = true;
10922 }
10923 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010924 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10925 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010926 mProcessesOnHold.remove(app);
10927
The Android Open Source Project4df24232009-03-05 14:34:35 -080010928 if (app == mHomeProcess) {
10929 mHomeProcess = null;
10930 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010931 if (app == mPreviousProcess) {
10932 mPreviousProcess = null;
10933 }
10934
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010935 if (restart && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010936 // We have components that still need to be running in the
10937 // process, so re-launch it.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010938 mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010939 startProcessLocked(app, "restart", app.processName);
10940 } else if (app.pid > 0 && app.pid != MY_PID) {
10941 // Goodbye!
10942 synchronized (mPidsSelfLocked) {
10943 mPidsSelfLocked.remove(app.pid);
10944 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10945 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010946 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010947 }
10948 }
10949
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010950 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10951 // Look through the content providers we are waiting to have launched,
10952 // and if any run in this process then either schedule a restart of
10953 // the process or kill the client waiting for it if this process has
10954 // gone bad.
10955 int NL = mLaunchingProviders.size();
10956 boolean restart = false;
10957 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010958 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010959 if (cpr.launchingApp == app) {
10960 if (!alwaysBad && !app.bad) {
10961 restart = true;
10962 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010963 removeDyingProviderLocked(app, cpr, true);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010964 NL = mLaunchingProviders.size();
10965 }
10966 }
10967 }
10968 return restart;
10969 }
10970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010971 // =========================================================
10972 // SERVICES
10973 // =========================================================
10974
10975 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
10976 ActivityManager.RunningServiceInfo info =
10977 new ActivityManager.RunningServiceInfo();
10978 info.service = r.name;
10979 if (r.app != null) {
10980 info.pid = r.app.pid;
10981 }
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010982 info.uid = r.appInfo.uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010983 info.process = r.processName;
10984 info.foreground = r.isForeground;
10985 info.activeSince = r.createTime;
10986 info.started = r.startRequested;
10987 info.clientCount = r.connections.size();
10988 info.crashCount = r.crashCount;
10989 info.lastActivityTime = r.lastActivity;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010990 if (r.isForeground) {
10991 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
10992 }
10993 if (r.startRequested) {
10994 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
10995 }
Dan Egnor42471dd2010-01-07 17:25:22 -080010996 if (r.app != null && r.app.pid == MY_PID) {
Dianne Hackborn3025ef32009-08-31 21:31:47 -070010997 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
10998 }
10999 if (r.app != null && r.app.persistent) {
11000 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
11001 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011002
11003 for (ArrayList<ConnectionRecord> connl : r.connections.values()) {
11004 for (int i=0; i<connl.size(); i++) {
11005 ConnectionRecord conn = connl.get(i);
11006 if (conn.clientLabel != 0) {
11007 info.clientPackage = conn.binding.client.info.packageName;
11008 info.clientLabel = conn.clientLabel;
11009 return info;
11010 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011011 }
11012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011013 return info;
11014 }
11015
11016 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
11017 int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011018 enforceNotIsolatedCaller("getServices");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011019 synchronized (this) {
11020 ArrayList<ActivityManager.RunningServiceInfo> res
11021 = new ArrayList<ActivityManager.RunningServiceInfo>();
11022
Amith Yamasani742a6712011-05-04 14:49:28 -070011023 int userId = UserId.getUserId(Binder.getCallingUid());
11024 if (mServiceMap.getAllServices(userId).size() > 0) {
11025 Iterator<ServiceRecord> it
11026 = mServiceMap.getAllServices(userId).iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011027 while (it.hasNext() && res.size() < maxNum) {
11028 res.add(makeRunningServiceInfoLocked(it.next()));
11029 }
11030 }
11031
11032 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
11033 ServiceRecord r = mRestartingServices.get(i);
11034 ActivityManager.RunningServiceInfo info =
11035 makeRunningServiceInfoLocked(r);
11036 info.restarting = r.nextRestartTime;
11037 res.add(info);
11038 }
11039
11040 return res;
11041 }
11042 }
11043
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011044 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011045 enforceNotIsolatedCaller("getRunningServiceControlPanel");
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011046 synchronized (this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011047 int userId = UserId.getUserId(Binder.getCallingUid());
11048 ServiceRecord r = mServiceMap.getServiceByName(name, userId);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011049 if (r != null) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011050 for (ArrayList<ConnectionRecord> conn : r.connections.values()) {
11051 for (int i=0; i<conn.size(); i++) {
11052 if (conn.get(i).clientIntent != null) {
11053 return conn.get(i).clientIntent;
11054 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070011055 }
11056 }
11057 }
11058 }
11059 return null;
11060 }
11061
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011062 private final ServiceRecord findServiceLocked(ComponentName name,
11063 IBinder token) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011064 ServiceRecord r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011065 return r == token ? r : null;
11066 }
11067
11068 private final class ServiceLookupResult {
11069 final ServiceRecord record;
11070 final String permission;
11071
11072 ServiceLookupResult(ServiceRecord _record, String _permission) {
11073 record = _record;
11074 permission = _permission;
11075 }
11076 };
11077
11078 private ServiceLookupResult findServiceLocked(Intent service,
Amith Yamasani483f3b02012-03-13 16:08:00 -070011079 String resolvedType, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011080 ServiceRecord r = null;
11081 if (service.getComponent() != null) {
Amith Yamasani483f3b02012-03-13 16:08:00 -070011082 r = mServiceMap.getServiceByName(service.getComponent(), userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011083 }
11084 if (r == null) {
11085 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Amith Yamasani483f3b02012-03-13 16:08:00 -070011086 r = mServiceMap.getServiceByIntent(filter, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011087 }
11088
11089 if (r == null) {
11090 try {
11091 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011092 AppGlobals.getPackageManager().resolveService(
Amith Yamasani483f3b02012-03-13 16:08:00 -070011093 service, resolvedType, 0, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011094 ServiceInfo sInfo =
11095 rInfo != null ? rInfo.serviceInfo : null;
11096 if (sInfo == null) {
11097 return null;
11098 }
11099
11100 ComponentName name = new ComponentName(
11101 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani742a6712011-05-04 14:49:28 -070011102 r = mServiceMap.getServiceByName(name, Binder.getOrigCallingUser());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011103 } catch (RemoteException ex) {
11104 // pm is in same process, this will never happen.
11105 }
11106 }
11107 if (r != null) {
11108 int callingPid = Binder.getCallingPid();
11109 int callingUid = Binder.getCallingUid();
11110 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011111 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011112 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011113 if (!r.exported) {
11114 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11115 + " from pid=" + callingPid
11116 + ", uid=" + callingUid
11117 + " that is not exported from uid " + r.appInfo.uid);
11118 return new ServiceLookupResult(null, "not exported from uid "
11119 + r.appInfo.uid);
11120 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011121 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011122 + " from pid=" + callingPid
11123 + ", uid=" + callingUid
11124 + " requires " + r.permission);
11125 return new ServiceLookupResult(null, r.permission);
11126 }
11127 return new ServiceLookupResult(r, null);
11128 }
11129 return null;
11130 }
11131
11132 private class ServiceRestarter implements Runnable {
11133 private ServiceRecord mService;
11134
11135 void setService(ServiceRecord service) {
11136 mService = service;
11137 }
11138
11139 public void run() {
11140 synchronized(ActivityManagerService.this) {
11141 performServiceRestartLocked(mService);
11142 }
11143 }
11144 }
11145
11146 private ServiceLookupResult retrieveServiceLocked(Intent service,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011147 String resolvedType, int callingPid, int callingUid, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011148 ServiceRecord r = null;
Amith Yamasani742a6712011-05-04 14:49:28 -070011149 if (DEBUG_SERVICE)
11150 Slog.v(TAG, "retrieveServiceLocked: " + service + " type=" + resolvedType
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011151 + " callingUid=" + callingUid);
Amith Yamasani742a6712011-05-04 14:49:28 -070011152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011153 if (service.getComponent() != null) {
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011154 r = mServiceMap.getServiceByName(service.getComponent(), userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011155 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011156 if (r == null) {
11157 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011158 r = mServiceMap.getServiceByIntent(filter, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -070011159 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011160 if (r == null) {
11161 try {
11162 ResolveInfo rInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070011163 AppGlobals.getPackageManager().resolveService(
Amith Yamasani483f3b02012-03-13 16:08:00 -070011164 service, resolvedType, STOCK_PM_FLAGS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011165 ServiceInfo sInfo =
11166 rInfo != null ? rInfo.serviceInfo : null;
11167 if (sInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011168 Slog.w(TAG, "Unable to start service " + service +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011169 ": not found");
11170 return null;
11171 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011172 if (userId > 0) {
Amith Yamasania4a54e22012-04-16 15:44:19 -070011173 if (isSingleton(sInfo.processName, sInfo.applicationInfo)) {
11174 userId = 0;
11175 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011176 sInfo.applicationInfo = getAppInfoForUser(sInfo.applicationInfo, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -070011177 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011178 ComponentName name = new ComponentName(
11179 sInfo.applicationInfo.packageName, sInfo.name);
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011180 r = mServiceMap.getServiceByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011181 if (r == null) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011182 Intent.FilterComparison filter = new Intent.FilterComparison(
11183 service.cloneFilter());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011184 ServiceRestarter res = new ServiceRestarter();
11185 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11186 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11187 synchronized (stats) {
11188 ss = stats.getServiceStatsLocked(
11189 sInfo.applicationInfo.uid, sInfo.packageName,
11190 sInfo.name);
11191 }
Dianne Hackbornb1c4a2a2010-01-19 15:36:42 -080011192 r = new ServiceRecord(this, ss, name, filter, sInfo, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011193 res.setService(r);
Amith Yamasani742a6712011-05-04 14:49:28 -070011194 mServiceMap.putServiceByName(name, UserId.getUserId(r.appInfo.uid), r);
11195 mServiceMap.putServiceByIntent(filter, UserId.getUserId(r.appInfo.uid), r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011196
11197 // Make sure this component isn't in the pending list.
11198 int N = mPendingServices.size();
11199 for (int i=0; i<N; i++) {
11200 ServiceRecord pr = mPendingServices.get(i);
11201 if (pr.name.equals(name)) {
11202 mPendingServices.remove(i);
11203 i--;
11204 N--;
11205 }
11206 }
11207 }
11208 } catch (RemoteException ex) {
11209 // pm is in same process, this will never happen.
11210 }
11211 }
11212 if (r != null) {
11213 if (checkComponentPermission(r.permission,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011214 callingPid, callingUid, r.appInfo.uid, r.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011215 != PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011216 if (!r.exported) {
11217 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
11218 + " from pid=" + callingPid
11219 + ", uid=" + callingUid
11220 + " that is not exported from uid " + r.appInfo.uid);
11221 return new ServiceLookupResult(null, "not exported from uid "
11222 + r.appInfo.uid);
11223 }
Joe Onorato8a9b2202010-02-26 18:56:32 -080011224 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011225 + " from pid=" + callingPid
11226 + ", uid=" + callingUid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011227 + " requires " + r.permission);
11228 return new ServiceLookupResult(null, r.permission);
11229 }
11230 return new ServiceLookupResult(r, null);
11231 }
11232 return null;
11233 }
11234
Dianne Hackborn287952c2010-09-22 22:34:31 -070011235 private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
11236 if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
11237 + why + " of " + r + " in app " + r.app);
11238 else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
11239 + why + " of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011240 long now = SystemClock.uptimeMillis();
11241 if (r.executeNesting == 0 && r.app != null) {
11242 if (r.app.executingServices.size() == 0) {
11243 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
11244 msg.obj = r.app;
11245 mHandler.sendMessageAtTime(msg, now+SERVICE_TIMEOUT);
11246 }
11247 r.app.executingServices.add(r);
11248 }
11249 r.executeNesting++;
11250 r.executingStart = now;
11251 }
11252
11253 private final void sendServiceArgsLocked(ServiceRecord r,
11254 boolean oomAdjusted) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011255 final int N = r.pendingStarts.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011256 if (N == 0) {
11257 return;
11258 }
11259
Dianne Hackborn39792d22010-08-19 18:01:52 -070011260 while (r.pendingStarts.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011261 try {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011262 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011263 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
11264 + r + " " + r.intent + " args=" + si.intent);
Dianne Hackborn3a28f222011-03-01 12:25:54 -080011265 if (si.intent == null && N > 1) {
11266 // If somehow we got a dummy null intent in the middle,
11267 // then skip it. DO NOT skip a null intent when it is
11268 // the only one in the list -- this is to support the
11269 // onStartCommand(null) case.
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011270 continue;
11271 }
Dianne Hackborn39792d22010-08-19 18:01:52 -070011272 si.deliveredTime = SystemClock.uptimeMillis();
11273 r.deliveredStarts.add(si);
11274 si.deliveryCount++;
Dianne Hackborn21c241e2012-03-08 13:57:23 -080011275 if (si.neededGrants != null) {
11276 grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
11277 si.getUriPermissionsLocked());
Dianne Hackborn39792d22010-08-19 18:01:52 -070011278 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070011279 bumpServiceExecutingLocked(r, "start");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011280 if (!oomAdjusted) {
11281 oomAdjusted = true;
11282 updateOomAdjLocked(r.app);
11283 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011284 int flags = 0;
Dianne Hackbornd8f10242012-05-08 17:14:58 -070011285 if (si.deliveryCount > 1) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011286 flags |= Service.START_FLAG_RETRY;
11287 }
11288 if (si.doneExecutingCount > 0) {
11289 flags |= Service.START_FLAG_REDELIVERY;
11290 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011291 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011292 } catch (RemoteException e) {
11293 // Remote process gone... we'll let the normal cleanup take
11294 // care of this.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011295 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011296 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011297 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011298 Slog.w(TAG, "Unexpected exception", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011299 break;
11300 }
11301 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011302 }
11303
11304 private final boolean requestServiceBindingLocked(ServiceRecord r,
11305 IntentBindRecord i, boolean rebind) {
11306 if (r.app == null || r.app.thread == null) {
11307 // If service is not currently running, can't yet bind.
11308 return false;
11309 }
11310 if ((!i.requested || rebind) && i.apps.size() > 0) {
11311 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011312 bumpServiceExecutingLocked(r, "bind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011313 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
11314 if (!rebind) {
11315 i.requested = true;
11316 }
11317 i.hasBound = true;
11318 i.doRebind = false;
11319 } catch (RemoteException e) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011320 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011321 return false;
11322 }
11323 }
11324 return true;
11325 }
11326
11327 private final void requestServiceBindingsLocked(ServiceRecord r) {
11328 Iterator<IntentBindRecord> bindings = r.bindings.values().iterator();
11329 while (bindings.hasNext()) {
11330 IntentBindRecord i = bindings.next();
11331 if (!requestServiceBindingLocked(r, i, false)) {
11332 break;
11333 }
11334 }
11335 }
11336
11337 private final void realStartServiceLocked(ServiceRecord r,
11338 ProcessRecord app) throws RemoteException {
11339 if (app.thread == null) {
11340 throw new RemoteException();
11341 }
Amith Yamasani742a6712011-05-04 14:49:28 -070011342 if (DEBUG_MU)
11343 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011344 + ", ProcessRecord.uid = " + app.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011345 r.app = app;
The Android Open Source Project10592532009-03-18 17:39:46 -070011346 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011347
11348 app.services.add(r);
Dianne Hackborn287952c2010-09-22 22:34:31 -070011349 bumpServiceExecutingLocked(r, "create");
Dianne Hackborndd71fc82009-12-16 19:24:32 -080011350 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011351
11352 boolean created = false;
11353 try {
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011354 mStringBuilder.setLength(0);
Dianne Hackborn21c241e2012-03-08 13:57:23 -080011355 r.intent.getIntent().toShortString(mStringBuilder, true, false, true, false);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011356 EventLog.writeEvent(EventLogTags.AM_CREATE_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011357 System.identityHashCode(r), r.shortName,
Dianne Hackborna33e3f72009-09-29 17:28:24 -070011358 mStringBuilder.toString(), r.app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011359 synchronized (r.stats.getBatteryStats()) {
11360 r.stats.startLaunchedLocked();
11361 }
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -070011362 ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011363 app.thread.scheduleCreateService(r, r.serviceInfo,
11364 compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo));
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011365 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011366 created = true;
11367 } finally {
11368 if (!created) {
11369 app.services.remove(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011370 scheduleServiceRestartLocked(r, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011371 }
11372 }
11373
11374 requestServiceBindingsLocked(r);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011375
11376 // If the service is in the started state, and there are no
11377 // pending arguments, then fake up one so its onStartCommand() will
11378 // be called.
11379 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011380 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn21c241e2012-03-08 13:57:23 -080011381 null, null));
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011382 }
11383
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011384 sendServiceArgsLocked(r, true);
11385 }
11386
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011387 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
11388 boolean allowCancel) {
11389 boolean canceled = false;
11390
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011391 final long now = SystemClock.uptimeMillis();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011392 long minDuration = SERVICE_RESTART_DURATION;
Dianne Hackborn6ccd2af2009-08-27 12:26:44 -070011393 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011394
Dianne Hackborn070783f2010-12-29 16:46:28 -080011395 if ((r.serviceInfo.applicationInfo.flags
11396 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11397 minDuration /= 4;
11398 }
11399
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011400 // Any delivered but not yet finished starts should be put back
11401 // on the pending list.
11402 final int N = r.deliveredStarts.size();
11403 if (N > 0) {
11404 for (int i=N-1; i>=0; i--) {
11405 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
Dianne Hackborn39792d22010-08-19 18:01:52 -070011406 si.removeUriPermissionsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011407 if (si.intent == null) {
11408 // We'll generate this again if needed.
11409 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
11410 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
11411 r.pendingStarts.add(0, si);
11412 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
11413 dur *= 2;
11414 if (minDuration < dur) minDuration = dur;
11415 if (resetTime < dur) resetTime = dur;
11416 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011417 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011418 + r.name);
11419 canceled = true;
11420 }
11421 }
11422 r.deliveredStarts.clear();
11423 }
11424
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011425 r.totalRestartCount++;
11426 if (r.restartDelay == 0) {
11427 r.restartCount++;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011428 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011429 } else {
11430 // If it has been a "reasonably long time" since the service
11431 // was started, then reset our restart duration back to
11432 // the beginning, so we don't infinitely increase the duration
11433 // on a service that just occasionally gets killed (which is
11434 // a normal case, due to process being killed to reclaim memory).
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011435 if (now > (r.restartTime+resetTime)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011436 r.restartCount = 1;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011437 r.restartDelay = minDuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011438 } else {
Dianne Hackborn070783f2010-12-29 16:46:28 -080011439 if ((r.serviceInfo.applicationInfo.flags
11440 &ApplicationInfo.FLAG_PERSISTENT) != 0) {
11441 // Services in peristent processes will restart much more
11442 // quickly, since they are pretty important. (Think SystemUI).
11443 r.restartDelay += minDuration/2;
11444 } else {
11445 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
11446 if (r.restartDelay < minDuration) {
11447 r.restartDelay = minDuration;
11448 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011449 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011450 }
11451 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011452
11453 r.nextRestartTime = now + r.restartDelay;
11454
11455 // Make sure that we don't end up restarting a bunch of services
11456 // all at the same time.
11457 boolean repeat;
11458 do {
11459 repeat = false;
11460 for (int i=mRestartingServices.size()-1; i>=0; i--) {
11461 ServiceRecord r2 = mRestartingServices.get(i);
11462 if (r2 != r && r.nextRestartTime
11463 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
11464 && r.nextRestartTime
11465 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
11466 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
11467 r.restartDelay = r.nextRestartTime - now;
11468 repeat = true;
11469 break;
11470 }
11471 }
11472 } while (repeat);
11473
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011474 if (!mRestartingServices.contains(r)) {
11475 mRestartingServices.add(r);
11476 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011477
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011478 r.cancelNotification();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011480 mHandler.removeCallbacks(r.restarter);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070011481 mHandler.postAtTime(r.restarter, r.nextRestartTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011482 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011483 Slog.w(TAG, "Scheduling restart of crashed service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011484 + r.shortName + " in " + r.restartDelay + "ms");
Doug Zongker2bec3d42009-12-04 12:52:44 -080011485 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011486 r.shortName, r.restartDelay);
11487
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011488 return canceled;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011489 }
11490
11491 final void performServiceRestartLocked(ServiceRecord r) {
11492 if (!mRestartingServices.contains(r)) {
11493 return;
11494 }
11495 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
11496 }
11497
11498 private final boolean unscheduleServiceRestartLocked(ServiceRecord r) {
11499 if (r.restartDelay == 0) {
11500 return false;
11501 }
11502 r.resetRestartCounter();
11503 mRestartingServices.remove(r);
11504 mHandler.removeCallbacks(r.restarter);
11505 return true;
11506 }
11507
11508 private final boolean bringUpServiceLocked(ServiceRecord r,
11509 int intentFlags, boolean whileRestarting) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011510 //Slog.i(TAG, "Bring up service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011511 //r.dump(" ");
11512
Dianne Hackborn36124872009-10-08 16:22:03 -070011513 if (r.app != null && r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011514 sendServiceArgsLocked(r, false);
11515 return true;
11516 }
11517
11518 if (!whileRestarting && r.restartDelay > 0) {
11519 // If waiting for a restart, then do nothing.
11520 return true;
11521 }
11522
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011523 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011524
Dianne Hackbornde42bb62009-08-05 12:26:15 -070011525 // We are now bringing the service up, so no longer in the
11526 // restarting state.
11527 mRestartingServices.remove(r);
11528
Dianne Hackborne7f97212011-02-24 14:40:20 -080011529 // Service is now being launched, its package can't be stopped.
11530 try {
11531 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -070011532 r.packageName, false, r.userId);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011533 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011534 } catch (IllegalArgumentException e) {
11535 Slog.w(TAG, "Failed trying to unstop package "
11536 + r.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011537 }
11538
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011539 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011540 final String appName = r.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011541 ProcessRecord app;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011542
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011543 if (!isolated) {
11544 app = getProcessRecordLocked(appName, r.appInfo.uid);
11545 if (DEBUG_MU)
11546 Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid + " app=" + app);
11547 if (app != null && app.thread != null) {
11548 try {
11549 app.addPackage(r.appInfo.packageName);
11550 realStartServiceLocked(r, app);
11551 return true;
11552 } catch (RemoteException e) {
11553 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
11554 }
11555
11556 // If a dead object exception was thrown -- fall through to
11557 // restart the application.
11558 }
11559 } else {
11560 // If this service runs in an isolated process, then each time
11561 // we call startProcessLocked() we will get a new isolated
11562 // process, starting another process if we are currently waiting
11563 // for a previous process to come up. To deal with this, we store
11564 // in the service any current isolated process it is running in or
11565 // waiting to have come up.
11566 app = r.isolatedProc;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011567 }
11568
Dianne Hackborn36124872009-10-08 16:22:03 -070011569 // Not running -- get it started, and enqueue this service record
11570 // to be executed when the app comes up.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011571 if (app == null) {
11572 if ((app=startProcessLocked(appName, r.appInfo, true, intentFlags,
11573 "service", r.name, false, isolated)) == null) {
11574 Slog.w(TAG, "Unable to launch app "
11575 + r.appInfo.packageName + "/"
11576 + r.appInfo.uid + " for service "
11577 + r.intent.getIntent() + ": process is bad");
11578 bringDownServiceLocked(r, true);
11579 return false;
11580 }
11581 if (isolated) {
11582 r.isolatedProc = app;
11583 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011584 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011585
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011586 if (!mPendingServices.contains(r)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011587 mPendingServices.add(r);
11588 }
Dianne Hackborn36124872009-10-08 16:22:03 -070011589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011590 return true;
11591 }
11592
11593 private final void bringDownServiceLocked(ServiceRecord r, boolean force) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011594 //Slog.i(TAG, "Bring down service:");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011595 //r.dump(" ");
11596
11597 // Does it still need to run?
11598 if (!force && r.startRequested) {
11599 return;
11600 }
11601 if (r.connections.size() > 0) {
11602 if (!force) {
11603 // XXX should probably keep a count of the number of auto-create
11604 // connections directly in the service.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011605 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011606 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011607 ArrayList<ConnectionRecord> cr = it.next();
11608 for (int i=0; i<cr.size(); i++) {
11609 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
11610 return;
11611 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011612 }
11613 }
11614 }
11615
11616 // Report to all of the connections that the service is no longer
11617 // available.
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011618 Iterator<ArrayList<ConnectionRecord>> it = r.connections.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011619 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011620 ArrayList<ConnectionRecord> c = it.next();
11621 for (int i=0; i<c.size(); i++) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011622 ConnectionRecord cr = c.get(i);
11623 // There is still a connection to the service that is
11624 // being brought down. Mark it as dead.
11625 cr.serviceDead = true;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011626 try {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070011627 cr.conn.connected(r.name, null);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011628 } catch (Exception e) {
11629 Slog.w(TAG, "Failure disconnecting service " + r.name +
11630 " to connection " + c.get(i).conn.asBinder() +
11631 " (in " + c.get(i).binding.client.processName + ")", e);
11632 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011633 }
11634 }
11635 }
11636
11637 // Tell the service that it has been unbound.
11638 if (r.bindings.size() > 0 && r.app != null && r.app.thread != null) {
11639 Iterator<IntentBindRecord> it = r.bindings.values().iterator();
11640 while (it.hasNext()) {
11641 IntentBindRecord ibr = it.next();
Joe Onorato8a9b2202010-02-26 18:56:32 -080011642 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011643 + ": hasBound=" + ibr.hasBound);
11644 if (r.app != null && r.app.thread != null && ibr.hasBound) {
11645 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011646 bumpServiceExecutingLocked(r, "bring down unbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011647 updateOomAdjLocked(r.app);
11648 ibr.hasBound = false;
11649 r.app.thread.scheduleUnbindService(r,
11650 ibr.intent.getIntent());
11651 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011652 Slog.w(TAG, "Exception when unbinding service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011653 + r.shortName, e);
11654 serviceDoneExecutingLocked(r, true);
11655 }
11656 }
11657 }
11658 }
11659
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011660 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Doug Zongker2bec3d42009-12-04 12:52:44 -080011661 EventLog.writeEvent(EventLogTags.AM_DESTROY_SERVICE,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011662 System.identityHashCode(r), r.shortName,
11663 (r.app != null) ? r.app.pid : -1);
11664
Amith Yamasani742a6712011-05-04 14:49:28 -070011665 mServiceMap.removeServiceByName(r.name, r.userId);
11666 mServiceMap.removeServiceByIntent(r.intent, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011667 r.totalRestartCount = 0;
11668 unscheduleServiceRestartLocked(r);
11669
11670 // Also make sure it is not on the pending list.
11671 int N = mPendingServices.size();
11672 for (int i=0; i<N; i++) {
11673 if (mPendingServices.get(i) == r) {
11674 mPendingServices.remove(i);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011675 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011676 i--;
11677 N--;
11678 }
11679 }
11680
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011681 r.cancelNotification();
11682 r.isForeground = false;
11683 r.foregroundId = 0;
11684 r.foregroundNoti = null;
11685
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011686 // Clear start entries.
Dianne Hackborn39792d22010-08-19 18:01:52 -070011687 r.clearDeliveredStartsLocked();
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011688 r.pendingStarts.clear();
11689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011690 if (r.app != null) {
11691 synchronized (r.stats.getBatteryStats()) {
11692 r.stats.stopLaunchedLocked();
11693 }
11694 r.app.services.remove(r);
11695 if (r.app.thread != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011696 try {
Dianne Hackborn287952c2010-09-22 22:34:31 -070011697 bumpServiceExecutingLocked(r, "stop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011698 mStoppingServices.add(r);
11699 updateOomAdjLocked(r.app);
11700 r.app.thread.scheduleStopService(r);
11701 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011702 Slog.w(TAG, "Exception when stopping service "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703 + r.shortName, e);
11704 serviceDoneExecutingLocked(r, true);
11705 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011706 updateServiceForegroundLocked(r.app, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011707 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011708 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011709 TAG, "Removed service that has no process: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011710 }
11711 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011712 if (DEBUG_SERVICE) Slog.v(
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011713 TAG, "Removed service that is not running: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011714 }
Vairavan Srinivasana207ce22010-12-23 13:51:48 -080011715
11716 if (r.bindings.size() > 0) {
11717 r.bindings.clear();
11718 }
11719
11720 if (r.restarter instanceof ServiceRestarter) {
11721 ((ServiceRestarter)r.restarter).setService(null);
11722 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011723 }
11724
11725 ComponentName startServiceLocked(IApplicationThread caller,
11726 Intent service, String resolvedType,
11727 int callingPid, int callingUid) {
11728 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011729 if (DEBUG_SERVICE) Slog.v(TAG, "startService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011730 + " type=" + resolvedType + " args=" + service.getExtras());
11731
11732 if (caller != null) {
11733 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11734 if (callerApp == null) {
11735 throw new SecurityException(
11736 "Unable to find app for caller " + caller
11737 + " (pid=" + Binder.getCallingPid()
11738 + ") when starting service " + service);
11739 }
11740 }
11741
11742 ServiceLookupResult res =
11743 retrieveServiceLocked(service, resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011744 callingPid, callingUid, UserId.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011745 if (res == null) {
11746 return null;
11747 }
11748 if (res.record == null) {
11749 return new ComponentName("!", res.permission != null
11750 ? res.permission : "private to package");
11751 }
11752 ServiceRecord r = res.record;
Dianne Hackborn21c241e2012-03-08 13:57:23 -080011753 NeededUriGrants neededGrants = checkGrantUriPermissionFromIntentLocked(
11754 callingUid, r.packageName, service, service.getFlags(), null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011755 if (unscheduleServiceRestartLocked(r)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070011756 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011757 }
11758 r.startRequested = true;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011759 r.callStart = false;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011760 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
Dianne Hackborn21c241e2012-03-08 13:57:23 -080011761 service, neededGrants));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011762 r.lastActivity = SystemClock.uptimeMillis();
11763 synchronized (r.stats.getBatteryStats()) {
11764 r.stats.startRunningLocked();
11765 }
11766 if (!bringUpServiceLocked(r, service.getFlags(), false)) {
11767 return new ComponentName("!", "Service process is bad");
11768 }
11769 return r.name;
11770 }
11771 }
11772
11773 public ComponentName startService(IApplicationThread caller, Intent service,
11774 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011775 enforceNotIsolatedCaller("startService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011776 // Refuse possible leaked file descriptors
11777 if (service != null && service.hasFileDescriptors() == true) {
11778 throw new IllegalArgumentException("File descriptors passed in Intent");
11779 }
11780
Amith Yamasani742a6712011-05-04 14:49:28 -070011781 if (DEBUG_SERVICE)
11782 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011783 synchronized(this) {
11784 final int callingPid = Binder.getCallingPid();
11785 final int callingUid = Binder.getCallingUid();
11786 final long origId = Binder.clearCallingIdentity();
11787 ComponentName res = startServiceLocked(caller, service,
11788 resolvedType, callingPid, callingUid);
11789 Binder.restoreCallingIdentity(origId);
11790 return res;
11791 }
11792 }
11793
11794 ComponentName startServiceInPackage(int uid,
11795 Intent service, String resolvedType) {
11796 synchronized(this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070011797 if (DEBUG_SERVICE)
11798 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 final long origId = Binder.clearCallingIdentity();
11800 ComponentName res = startServiceLocked(null, service,
11801 resolvedType, -1, uid);
11802 Binder.restoreCallingIdentity(origId);
11803 return res;
11804 }
11805 }
11806
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011807 private void stopServiceLocked(ServiceRecord service) {
11808 synchronized (service.stats.getBatteryStats()) {
11809 service.stats.stopRunningLocked();
11810 }
11811 service.startRequested = false;
11812 service.callStart = false;
11813 bringDownServiceLocked(service, false);
11814 }
11815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011816 public int stopService(IApplicationThread caller, Intent service,
11817 String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011818 enforceNotIsolatedCaller("stopService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011819 // Refuse possible leaked file descriptors
11820 if (service != null && service.hasFileDescriptors() == true) {
11821 throw new IllegalArgumentException("File descriptors passed in Intent");
11822 }
11823
11824 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011825 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011826 + " type=" + resolvedType);
11827
11828 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11829 if (caller != null && callerApp == null) {
11830 throw new SecurityException(
11831 "Unable to find app for caller " + caller
11832 + " (pid=" + Binder.getCallingPid()
11833 + ") when stopping service " + service);
11834 }
11835
11836 // If this service is active, make sure it is stopped.
Amith Yamasani483f3b02012-03-13 16:08:00 -070011837 ServiceLookupResult r = findServiceLocked(service, resolvedType,
11838 callerApp == null ? UserId.getCallingUserId() : callerApp.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011839 if (r != null) {
11840 if (r.record != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011841 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011842 try {
11843 stopServiceLocked(r.record);
11844 } finally {
11845 Binder.restoreCallingIdentity(origId);
11846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011847 return 1;
11848 }
11849 return -1;
11850 }
11851 }
11852
11853 return 0;
11854 }
11855
11856 public IBinder peekService(Intent service, String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011857 enforceNotIsolatedCaller("peekService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011858 // Refuse possible leaked file descriptors
11859 if (service != null && service.hasFileDescriptors() == true) {
11860 throw new IllegalArgumentException("File descriptors passed in Intent");
11861 }
11862
11863 IBinder ret = null;
11864
11865 synchronized(this) {
Amith Yamasani483f3b02012-03-13 16:08:00 -070011866 ServiceLookupResult r = findServiceLocked(service, resolvedType,
11867 UserId.getCallingUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011868
11869 if (r != null) {
11870 // r.record is null if findServiceLocked() failed the caller permission check
11871 if (r.record == null) {
11872 throw new SecurityException(
11873 "Permission Denial: Accessing service " + r.record.name
11874 + " from pid=" + Binder.getCallingPid()
11875 + ", uid=" + Binder.getCallingUid()
11876 + " requires " + r.permission);
11877 }
11878 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
11879 if (ib != null) {
11880 ret = ib.binder;
11881 }
11882 }
11883 }
11884
11885 return ret;
11886 }
11887
11888 public boolean stopServiceToken(ComponentName className, IBinder token,
11889 int startId) {
11890 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011891 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011892 + " " + token + " startId=" + startId);
11893 ServiceRecord r = findServiceLocked(className, token);
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011894 if (r != null) {
11895 if (startId >= 0) {
11896 // Asked to only stop if done with all work. Note that
11897 // to avoid leaks, we will take this as dropping all
11898 // start items up to and including this one.
11899 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
11900 if (si != null) {
11901 while (r.deliveredStarts.size() > 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -070011902 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
11903 cur.removeUriPermissionsLocked();
11904 if (cur == si) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011905 break;
11906 }
11907 }
11908 }
11909
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070011910 if (r.getLastStartId() != startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011911 return false;
11912 }
11913
11914 if (r.deliveredStarts.size() > 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011915 Slog.w(TAG, "stopServiceToken startId " + startId
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011916 + " is last, but have " + r.deliveredStarts.size()
11917 + " remaining args");
11918 }
11919 }
11920
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 synchronized (r.stats.getBatteryStats()) {
11922 r.stats.stopRunningLocked();
11923 r.startRequested = false;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011924 r.callStart = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011925 }
11926 final long origId = Binder.clearCallingIdentity();
11927 bringDownServiceLocked(r, false);
11928 Binder.restoreCallingIdentity(origId);
11929 return true;
11930 }
11931 }
11932 return false;
11933 }
11934
11935 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011936 int id, Notification notification, boolean removeNotification) {
11937 final long origId = Binder.clearCallingIdentity();
11938 try {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011939 synchronized(this) {
11940 ServiceRecord r = findServiceLocked(className, token);
11941 if (r != null) {
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011942 if (id != 0) {
11943 if (notification == null) {
11944 throw new IllegalArgumentException("null notification");
11945 }
11946 if (r.foregroundId != id) {
11947 r.cancelNotification();
11948 r.foregroundId = id;
11949 }
11950 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
11951 r.foregroundNoti = notification;
11952 r.isForeground = true;
11953 r.postNotification();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011954 if (r.app != null) {
11955 updateServiceForegroundLocked(r.app, true);
11956 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011957 } else {
11958 if (r.isForeground) {
11959 r.isForeground = false;
11960 if (r.app != null) {
Dianne Hackborn8633e682010-04-22 16:03:41 -070011961 updateLruProcessLocked(r.app, false, true);
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011962 updateServiceForegroundLocked(r.app, true);
11963 }
11964 }
11965 if (removeNotification) {
11966 r.cancelNotification();
11967 r.foregroundId = 0;
11968 r.foregroundNoti = null;
11969 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011970 }
11971 }
11972 }
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011973 } finally {
11974 Binder.restoreCallingIdentity(origId);
11975 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011976 }
11977
11978 public void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
11979 boolean anyForeground = false;
Dianne Hackborn860755f2010-06-03 18:47:52 -070011980 for (ServiceRecord sr : proc.services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011981 if (sr.isForeground) {
11982 anyForeground = true;
11983 break;
11984 }
11985 }
11986 if (anyForeground != proc.foregroundServices) {
11987 proc.foregroundServices = anyForeground;
11988 if (oomAdj) {
11989 updateOomAdjLocked();
11990 }
11991 }
11992 }
Amith Yamasania4a54e22012-04-16 15:44:19 -070011993
11994 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo) {
11995 boolean result = false;
11996 if (UserId.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
11997 result = false;
11998 } else if (componentProcessName == aInfo.packageName) {
11999 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
12000 } else if ("system".equals(componentProcessName)) {
12001 result = true;
12002 }
12003 if (DEBUG_MU) {
12004 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo + ") = " + result);
12005 }
12006 return result;
12007 }
12008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009 public int bindService(IApplicationThread caller, IBinder token,
12010 Intent service, String resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080012011 IServiceConnection connection, int flags, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012012 enforceNotIsolatedCaller("bindService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012013 // Refuse possible leaked file descriptors
12014 if (service != null && service.hasFileDescriptors() == true) {
12015 throw new IllegalArgumentException("File descriptors passed in Intent");
12016 }
12017
Amith Yamasani37ce3a82012-02-06 12:04:42 -080012018 checkValidCaller(Binder.getCallingUid(), userId);
12019
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012020 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012021 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012022 + " type=" + resolvedType + " conn=" + connection.asBinder()
12023 + " flags=0x" + Integer.toHexString(flags));
Amith Yamasani742a6712011-05-04 14:49:28 -070012024 if (DEBUG_MU)
12025 Slog.i(TAG_MU, "bindService uid=" + Binder.getCallingUid() + " origUid="
12026 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012027 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12028 if (callerApp == null) {
12029 throw new SecurityException(
12030 "Unable to find app for caller " + caller
12031 + " (pid=" + Binder.getCallingPid()
12032 + ") when binding service " + service);
12033 }
12034
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012035 ActivityRecord activity = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012036 if (token != null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012037 activity = mMainStack.isInStackLocked(token);
12038 if (activity == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012039 Slog.w(TAG, "Binding with unknown activity: " + token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012040 return 0;
12041 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012042 }
12043
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012044 int clientLabel = 0;
12045 PendingIntent clientIntent = null;
12046
12047 if (callerApp.info.uid == Process.SYSTEM_UID) {
12048 // Hacky kind of thing -- allow system stuff to tell us
12049 // what they are, so we can report this elsewhere for
12050 // others to know why certain services are running.
12051 try {
12052 clientIntent = (PendingIntent)service.getParcelableExtra(
12053 Intent.EXTRA_CLIENT_INTENT);
12054 } catch (RuntimeException e) {
12055 }
12056 if (clientIntent != null) {
12057 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
12058 if (clientLabel != 0) {
12059 // There are no useful extras in the intent, trash them.
12060 // System code calling with this stuff just needs to know
12061 // this will happen.
12062 service = service.cloneFilter();
12063 }
12064 }
12065 }
12066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012067 ServiceLookupResult res =
12068 retrieveServiceLocked(service, resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080012069 Binder.getCallingPid(), Binder.getCallingUid(), userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012070 if (res == null) {
12071 return 0;
12072 }
12073 if (res.record == null) {
12074 return -1;
12075 }
Amith Yamasania4a54e22012-04-16 15:44:19 -070012076 if (isSingleton(res.record.processName, res.record.appInfo)) {
12077 userId = 0;
12078 res = retrieveServiceLocked(service, resolvedType, Binder.getCallingPid(),
12079 Binder.getCallingUid(), 0);
12080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012081 ServiceRecord s = res.record;
12082
12083 final long origId = Binder.clearCallingIdentity();
12084
12085 if (unscheduleServiceRestartLocked(s)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012086 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012087 + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012088 }
12089
12090 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
12091 ConnectionRecord c = new ConnectionRecord(b, activity,
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070012092 connection, flags, clientLabel, clientIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012093
12094 IBinder binder = connection.asBinder();
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012095 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12096 if (clist == null) {
12097 clist = new ArrayList<ConnectionRecord>();
12098 s.connections.put(binder, clist);
12099 }
12100 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012101 b.connections.add(c);
12102 if (activity != null) {
12103 if (activity.connections == null) {
12104 activity.connections = new HashSet<ConnectionRecord>();
12105 }
12106 activity.connections.add(c);
12107 }
12108 b.client.connections.add(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012109 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12110 b.client.hasAboveClient = true;
12111 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012112 clist = mServiceConnections.get(binder);
12113 if (clist == null) {
12114 clist = new ArrayList<ConnectionRecord>();
12115 mServiceConnections.put(binder, clist);
12116 }
12117 clist.add(c);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012118
12119 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
12120 s.lastActivity = SystemClock.uptimeMillis();
12121 if (!bringUpServiceLocked(s, service.getFlags(), false)) {
12122 return 0;
12123 }
12124 }
12125
12126 if (s.app != null) {
12127 // This could have made the service more important.
12128 updateOomAdjLocked(s.app);
12129 }
12130
Joe Onorato8a9b2202010-02-26 18:56:32 -080012131 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012132 + ": received=" + b.intent.received
12133 + " apps=" + b.intent.apps.size()
12134 + " doRebind=" + b.intent.doRebind);
12135
12136 if (s.app != null && b.intent.received) {
12137 // Service is already running, so we can immediately
12138 // publish the connection.
12139 try {
12140 c.conn.connected(s.name, b.intent.binder);
12141 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012142 Slog.w(TAG, "Failure sending service " + s.shortName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012143 + " to connection " + c.conn.asBinder()
12144 + " (in " + c.binding.client.processName + ")", e);
12145 }
12146
12147 // If this is the first app connected back to this binding,
12148 // and the service had previously asked to be told when
12149 // rebound, then do so.
12150 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
12151 requestServiceBindingLocked(s, b.intent, true);
12152 }
12153 } else if (!b.intent.requested) {
12154 requestServiceBindingLocked(s, b.intent, false);
12155 }
12156
12157 Binder.restoreCallingIdentity(origId);
12158 }
12159
12160 return 1;
12161 }
12162
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012163 void removeConnectionLocked(
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012164 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012165 IBinder binder = c.conn.asBinder();
12166 AppBindRecord b = c.binding;
12167 ServiceRecord s = b.service;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012168 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
12169 if (clist != null) {
12170 clist.remove(c);
12171 if (clist.size() == 0) {
12172 s.connections.remove(binder);
12173 }
12174 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012175 b.connections.remove(c);
12176 if (c.activity != null && c.activity != skipAct) {
12177 if (c.activity.connections != null) {
12178 c.activity.connections.remove(c);
12179 }
12180 }
12181 if (b.client != skipApp) {
12182 b.client.connections.remove(c);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012183 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
12184 b.client.updateHasAboveClientLocked();
12185 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012186 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012187 clist = mServiceConnections.get(binder);
12188 if (clist != null) {
12189 clist.remove(c);
12190 if (clist.size() == 0) {
12191 mServiceConnections.remove(binder);
12192 }
12193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012194
12195 if (b.connections.size() == 0) {
12196 b.intent.apps.remove(b.client);
12197 }
12198
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012199 if (!c.serviceDead) {
12200 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
12201 + ": shouldUnbind=" + b.intent.hasBound);
12202 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
12203 && b.intent.hasBound) {
12204 try {
12205 bumpServiceExecutingLocked(s, "unbind");
12206 updateOomAdjLocked(s.app);
12207 b.intent.hasBound = false;
12208 // Assume the client doesn't want to know about a rebind;
12209 // we will deal with that later if it asks for one.
12210 b.intent.doRebind = false;
12211 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
12212 } catch (Exception e) {
12213 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
12214 serviceDoneExecutingLocked(s, true);
12215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012216 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012217
12218 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
12219 bringDownServiceLocked(s, false);
12220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012221 }
12222 }
12223
12224 public boolean unbindService(IServiceConnection connection) {
12225 synchronized (this) {
12226 IBinder binder = connection.asBinder();
Joe Onorato8a9b2202010-02-26 18:56:32 -080012227 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012228 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
12229 if (clist == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012230 Slog.w(TAG, "Unbind failed: could not find connection for "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012231 + connection.asBinder());
12232 return false;
12233 }
12234
12235 final long origId = Binder.clearCallingIdentity();
12236
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012237 while (clist.size() > 0) {
12238 ConnectionRecord r = clist.get(0);
12239 removeConnectionLocked(r, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012240
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012241 if (r.binding.service.app != null) {
12242 // This could have made the service less important.
12243 updateOomAdjLocked(r.binding.service.app);
12244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012245 }
12246
12247 Binder.restoreCallingIdentity(origId);
12248 }
12249
12250 return true;
12251 }
12252
12253 public void publishService(IBinder token, Intent intent, IBinder service) {
12254 // Refuse possible leaked file descriptors
12255 if (intent != null && intent.hasFileDescriptors() == true) {
12256 throw new IllegalArgumentException("File descriptors passed in Intent");
12257 }
12258
12259 synchronized(this) {
12260 if (!(token instanceof ServiceRecord)) {
12261 throw new IllegalArgumentException("Invalid service token");
12262 }
12263 ServiceRecord r = (ServiceRecord)token;
12264
12265 final long origId = Binder.clearCallingIdentity();
12266
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012267 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012268 + " " + intent + ": " + service);
12269 if (r != null) {
12270 Intent.FilterComparison filter
12271 = new Intent.FilterComparison(intent);
12272 IntentBindRecord b = r.bindings.get(filter);
12273 if (b != null && !b.received) {
12274 b.binder = service;
12275 b.requested = true;
12276 b.received = true;
12277 if (r.connections.size() > 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012278 Iterator<ArrayList<ConnectionRecord>> it
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012279 = r.connections.values().iterator();
12280 while (it.hasNext()) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012281 ArrayList<ConnectionRecord> clist = it.next();
12282 for (int i=0; i<clist.size(); i++) {
12283 ConnectionRecord c = clist.get(i);
12284 if (!filter.equals(c.binding.intent.intent)) {
12285 if (DEBUG_SERVICE) Slog.v(
12286 TAG, "Not publishing to: " + c);
12287 if (DEBUG_SERVICE) Slog.v(
12288 TAG, "Bound intent: " + c.binding.intent.intent);
12289 if (DEBUG_SERVICE) Slog.v(
12290 TAG, "Published intent: " + intent);
12291 continue;
12292 }
12293 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
12294 try {
12295 c.conn.connected(r.name, service);
12296 } catch (Exception e) {
12297 Slog.w(TAG, "Failure sending service " + r.name +
12298 " to connection " + c.conn.asBinder() +
12299 " (in " + c.binding.client.processName + ")", e);
12300 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012301 }
12302 }
12303 }
12304 }
12305
12306 serviceDoneExecutingLocked(r, mStoppingServices.contains(r));
12307
12308 Binder.restoreCallingIdentity(origId);
12309 }
12310 }
12311 }
12312
12313 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
12314 // Refuse possible leaked file descriptors
12315 if (intent != null && intent.hasFileDescriptors() == true) {
12316 throw new IllegalArgumentException("File descriptors passed in Intent");
12317 }
12318
12319 synchronized(this) {
12320 if (!(token instanceof ServiceRecord)) {
12321 throw new IllegalArgumentException("Invalid service token");
12322 }
12323 ServiceRecord r = (ServiceRecord)token;
12324
12325 final long origId = Binder.clearCallingIdentity();
12326
12327 if (r != null) {
12328 Intent.FilterComparison filter
12329 = new Intent.FilterComparison(intent);
12330 IntentBindRecord b = r.bindings.get(filter);
Joe Onorato8a9b2202010-02-26 18:56:32 -080012331 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 + " at " + b + ": apps="
12333 + (b != null ? b.apps.size() : 0));
Per Edelberg78f9fff2010-08-30 20:01:35 +020012334
12335 boolean inStopping = mStoppingServices.contains(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012336 if (b != null) {
Per Edelberg78f9fff2010-08-30 20:01:35 +020012337 if (b.apps.size() > 0 && !inStopping) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 // Applications have already bound since the last
12339 // unbind, so just rebind right here.
12340 requestServiceBindingLocked(r, b, true);
12341 } else {
12342 // Note to tell the service the next time there is
12343 // a new client.
12344 b.doRebind = true;
12345 }
12346 }
12347
Per Edelberg78f9fff2010-08-30 20:01:35 +020012348 serviceDoneExecutingLocked(r, inStopping);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349
12350 Binder.restoreCallingIdentity(origId);
12351 }
12352 }
12353 }
12354
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012355 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012356 synchronized(this) {
12357 if (!(token instanceof ServiceRecord)) {
12358 throw new IllegalArgumentException("Invalid service token");
12359 }
12360 ServiceRecord r = (ServiceRecord)token;
12361 boolean inStopping = mStoppingServices.contains(token);
12362 if (r != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012363 if (r != token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012364 Slog.w(TAG, "Done executing service " + r.name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012365 + " with incorrect token: given " + token
12366 + ", expected " + r);
12367 return;
12368 }
12369
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012370 if (type == 1) {
12371 // This is a call from a service start... take care of
12372 // book-keeping.
12373 r.callStart = true;
12374 switch (res) {
12375 case Service.START_STICKY_COMPATIBILITY:
12376 case Service.START_STICKY: {
12377 // We are done with the associated start arguments.
12378 r.findDeliveredStart(startId, true);
12379 // Don't stop if killed.
12380 r.stopIfKilled = false;
12381 break;
12382 }
12383 case Service.START_NOT_STICKY: {
12384 // We are done with the associated start arguments.
12385 r.findDeliveredStart(startId, true);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012386 if (r.getLastStartId() == startId) {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012387 // There is no more work, and this service
12388 // doesn't want to hang around if killed.
12389 r.stopIfKilled = true;
12390 }
12391 break;
12392 }
12393 case Service.START_REDELIVER_INTENT: {
12394 // We'll keep this item until they explicitly
12395 // call stop for it, but keep track of the fact
12396 // that it was delivered.
12397 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
12398 if (si != null) {
12399 si.deliveryCount = 0;
12400 si.doneExecutingCount++;
12401 // Don't stop if killed.
12402 r.stopIfKilled = true;
12403 }
12404 break;
12405 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070012406 case Service.START_TASK_REMOVED_COMPLETE: {
12407 // Special processing for onTaskRemoved(). Don't
12408 // impact normal onStartCommand() processing.
12409 r.findDeliveredStart(startId, true);
12410 break;
12411 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070012412 default:
12413 throw new IllegalArgumentException(
12414 "Unknown service start result: " + res);
12415 }
12416 if (res == Service.START_STICKY_COMPATIBILITY) {
12417 r.callStart = false;
12418 }
12419 }
Amith Yamasani742a6712011-05-04 14:49:28 -070012420 if (DEBUG_MU)
12421 Slog.v(TAG_MU, "before serviceDontExecutingLocked, uid="
12422 + Binder.getOrigCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012423 final long origId = Binder.clearCallingIdentity();
12424 serviceDoneExecutingLocked(r, inStopping);
12425 Binder.restoreCallingIdentity(origId);
12426 } else {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012427 Slog.w(TAG, "Done executing unknown service from pid "
12428 + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012429 }
12430 }
12431 }
12432
12433 public void serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012434 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
12435 + ": nesting=" + r.executeNesting
12436 + ", inStopping=" + inStopping + ", app=" + r.app);
Dianne Hackborn287952c2010-09-22 22:34:31 -070012437 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012438 r.executeNesting--;
12439 if (r.executeNesting <= 0 && r.app != null) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012440 if (DEBUG_SERVICE) Slog.v(TAG,
12441 "Nesting at 0 of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012442 r.app.executingServices.remove(r);
12443 if (r.app.executingServices.size() == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012444 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
12445 "No more executingServices of " + r.shortName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012446 mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
12447 }
12448 if (inStopping) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012449 if (DEBUG_SERVICE) Slog.v(TAG,
12450 "doneExecuting remove stopping " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012451 mStoppingServices.remove(r);
Mattias Petersson3996b412010-10-27 09:32:51 +020012452 r.bindings.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012453 }
12454 updateOomAdjLocked(r.app);
12455 }
12456 }
12457
12458 void serviceTimeout(ProcessRecord proc) {
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012459 String anrMessage = null;
12460
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012461 synchronized(this) {
12462 if (proc.executingServices.size() == 0 || proc.thread == null) {
12463 return;
12464 }
12465 long maxTime = SystemClock.uptimeMillis() - SERVICE_TIMEOUT;
12466 Iterator<ServiceRecord> it = proc.executingServices.iterator();
12467 ServiceRecord timeout = null;
12468 long nextTime = 0;
12469 while (it.hasNext()) {
12470 ServiceRecord sr = it.next();
12471 if (sr.executingStart < maxTime) {
12472 timeout = sr;
12473 break;
12474 }
12475 if (sr.executingStart > nextTime) {
12476 nextTime = sr.executingStart;
12477 }
12478 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012479 if (timeout != null && mLruProcesses.contains(proc)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012480 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012481 anrMessage = "Executing service " + timeout.shortName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012482 } else {
12483 Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
12484 msg.obj = proc;
12485 mHandler.sendMessageAtTime(msg, nextTime+SERVICE_TIMEOUT);
12486 }
12487 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012488
12489 if (anrMessage != null) {
12490 appNotResponding(proc, null, null, anrMessage);
12491 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012492 }
12493
12494 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070012495 // BACKUP AND RESTORE
12496 // =========================================================
12497
12498 // Cause the target app to be launched if necessary and its backup agent
12499 // instantiated. The backup agent will invoke backupAgentCreated() on the
12500 // activity manager to announce its creation.
12501 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012502 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012503 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
12504
12505 synchronized(this) {
12506 // !!! TODO: currently no check here that we're already bound
12507 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
12508 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12509 synchronized (stats) {
12510 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
12511 }
12512
Dianne Hackborne7f97212011-02-24 14:40:20 -080012513 // Backup agent is now in use, its package can't be stopped.
12514 try {
12515 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -070012516 app.packageName, false, UserId.getUserId(app.uid));
Dianne Hackborne7f97212011-02-24 14:40:20 -080012517 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080012518 } catch (IllegalArgumentException e) {
12519 Slog.w(TAG, "Failed trying to unstop package "
12520 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080012521 }
12522
Christopher Tate181fafa2009-05-14 11:12:14 -070012523 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070012524 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
12525 ? new ComponentName(app.packageName, app.backupAgentName)
12526 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070012527 // startProcessLocked() returns existing proc's record if it's already running
12528 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080012529 false, 0, "backup", hostingName, false, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070012530 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012531 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070012532 return false;
12533 }
12534
12535 r.app = proc;
12536 mBackupTarget = r;
12537 mBackupAppName = app.packageName;
12538
Christopher Tate6fa95972009-06-05 18:43:55 -070012539 // Try not to kill the process during backup
12540 updateOomAdjLocked(proc);
12541
Christopher Tate181fafa2009-05-14 11:12:14 -070012542 // If the process is already attached, schedule the creation of the backup agent now.
12543 // If it is not yet live, this will be done when it attaches to the framework.
12544 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012545 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070012546 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012547 proc.thread.scheduleCreateBackupAgent(app,
12548 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070012549 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070012550 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070012551 }
12552 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012553 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070012554 }
12555 // Invariants: at this point, the target app process exists and the application
12556 // is either already running or in the process of coming up. mBackupTarget and
12557 // mBackupAppName describe the app, so that when it binds back to the AM we
12558 // know that it's scheduled for a backup-agent operation.
12559 }
12560
12561 return true;
12562 }
12563
12564 // A backup agent has just come up
12565 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012566 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070012567 + " = " + agent);
12568
12569 synchronized(this) {
12570 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012571 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070012572 return;
12573 }
Dianne Hackborn06740692010-09-22 22:46:21 -070012574 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012575
Dianne Hackborn06740692010-09-22 22:46:21 -070012576 long oldIdent = Binder.clearCallingIdentity();
12577 try {
12578 IBackupManager bm = IBackupManager.Stub.asInterface(
12579 ServiceManager.getService(Context.BACKUP_SERVICE));
12580 bm.agentConnected(agentPackageName, agent);
12581 } catch (RemoteException e) {
12582 // can't happen; the backup manager service is local
12583 } catch (Exception e) {
12584 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
12585 e.printStackTrace();
12586 } finally {
12587 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070012588 }
12589 }
12590
12591 // done with this agent
12592 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012593 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070012594 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012595 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070012596 return;
12597 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012598
12599 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070012600 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012601 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070012602 return;
12603 }
12604
Christopher Tate181fafa2009-05-14 11:12:14 -070012605 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012606 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070012607 return;
12608 }
12609
Christopher Tate6fa95972009-06-05 18:43:55 -070012610 ProcessRecord proc = mBackupTarget.app;
12611 mBackupTarget = null;
12612 mBackupAppName = null;
12613
12614 // Not backing this app up any more; reset its OOM adjustment
12615 updateOomAdjLocked(proc);
12616
Christopher Tatec7b31e32009-06-10 15:49:30 -070012617 // If the app crashed during backup, 'thread' will be null here
12618 if (proc.thread != null) {
12619 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040012620 proc.thread.scheduleDestroyBackupAgent(appInfo,
12621 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070012622 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012623 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070012624 e.printStackTrace();
12625 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012626 }
Christopher Tate181fafa2009-05-14 11:12:14 -070012627 }
12628 }
12629 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012630 // BROADCASTS
12631 // =========================================================
12632
Josh Bartel7f208742010-02-25 11:01:44 -060012633 private final List getStickiesLocked(String action, IntentFilter filter,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012634 List cur) {
12635 final ContentResolver resolver = mContext.getContentResolver();
12636 final ArrayList<Intent> list = mStickyBroadcasts.get(action);
12637 if (list == null) {
12638 return cur;
12639 }
12640 int N = list.size();
12641 for (int i=0; i<N; i++) {
12642 Intent intent = list.get(i);
12643 if (filter.match(resolver, intent, true, TAG) >= 0) {
12644 if (cur == null) {
12645 cur = new ArrayList<Intent>();
12646 }
12647 cur.add(intent);
12648 }
12649 }
12650 return cur;
12651 }
12652
Christopher Tatef46723b2012-01-26 14:19:24 -080012653 boolean isPendingBroadcastProcessLocked(int pid) {
12654 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
12655 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
12656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012657
Christopher Tatef46723b2012-01-26 14:19:24 -080012658 void skipPendingBroadcastLocked(int pid) {
12659 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
12660 for (BroadcastQueue queue : mBroadcastQueues) {
12661 queue.skipPendingBroadcastLocked(pid);
12662 }
12663 }
12664
12665 // The app just attached; send any pending broadcasts that it should receive
12666 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
12667 boolean didSomething = false;
12668 for (BroadcastQueue queue : mBroadcastQueues) {
12669 didSomething |= queue.sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012670 }
Christopher Tatef46723b2012-01-26 14:19:24 -080012671 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012672 }
12673
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012674 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012675 IIntentReceiver receiver, IntentFilter filter, String permission) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012676 enforceNotIsolatedCaller("registerReceiver");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012677 synchronized(this) {
12678 ProcessRecord callerApp = null;
12679 if (caller != null) {
12680 callerApp = getRecordForAppLocked(caller);
12681 if (callerApp == null) {
12682 throw new SecurityException(
12683 "Unable to find app for caller " + caller
12684 + " (pid=" + Binder.getCallingPid()
12685 + ") when registering receiver " + receiver);
12686 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012687 if (callerApp.info.uid != Process.SYSTEM_UID &&
12688 !callerApp.pkgList.contains(callerPackage)) {
12689 throw new SecurityException("Given caller package " + callerPackage
12690 + " is not running in process " + callerApp);
12691 }
12692 } else {
12693 callerPackage = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012694 }
12695
12696 List allSticky = null;
12697
12698 // Look for any matching sticky broadcasts...
12699 Iterator actions = filter.actionsIterator();
12700 if (actions != null) {
12701 while (actions.hasNext()) {
12702 String action = (String)actions.next();
Josh Bartel7f208742010-02-25 11:01:44 -060012703 allSticky = getStickiesLocked(action, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012704 }
12705 } else {
Josh Bartel7f208742010-02-25 11:01:44 -060012706 allSticky = getStickiesLocked(null, filter, allSticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012707 }
12708
12709 // The first sticky in the list is returned directly back to
12710 // the client.
12711 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
12712
Joe Onorato8a9b2202010-02-26 18:56:32 -080012713 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012714 + ": " + sticky);
12715
12716 if (receiver == null) {
12717 return sticky;
12718 }
12719
12720 ReceiverList rl
12721 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
12722 if (rl == null) {
12723 rl = new ReceiverList(this, callerApp,
12724 Binder.getCallingPid(),
12725 Binder.getCallingUid(), receiver);
12726 if (rl.app != null) {
12727 rl.app.receivers.add(rl);
12728 } else {
12729 try {
12730 receiver.asBinder().linkToDeath(rl, 0);
12731 } catch (RemoteException e) {
12732 return sticky;
12733 }
12734 rl.linkedToDeath = true;
12735 }
12736 mRegisteredReceivers.put(receiver.asBinder(), rl);
12737 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070012738 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, permission);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012739 rl.add(bf);
12740 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012741 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012742 }
12743 mReceiverResolver.addFilter(bf);
12744
12745 // Enqueue broadcasts for all existing stickies that match
12746 // this filter.
12747 if (allSticky != null) {
12748 ArrayList receivers = new ArrayList();
12749 receivers.add(bf);
12750
12751 int N = allSticky.size();
12752 for (int i=0; i<N; i++) {
12753 Intent intent = (Intent)allSticky.get(i);
Christopher Tatef46723b2012-01-26 14:19:24 -080012754 BroadcastQueue queue = broadcastQueueForIntent(intent);
12755 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012756 null, -1, -1, null, receivers, null, 0, null, null,
Dianne Hackborn12527f92009-11-11 17:39:50 -080012757 false, true, true);
Christopher Tatef46723b2012-01-26 14:19:24 -080012758 queue.enqueueParallelBroadcastLocked(r);
12759 queue.scheduleBroadcastsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012760 }
12761 }
12762
12763 return sticky;
12764 }
12765 }
12766
12767 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012768 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012769
Christopher Tatef46723b2012-01-26 14:19:24 -080012770 final long origId = Binder.clearCallingIdentity();
12771 try {
12772 boolean doTrim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012773
Christopher Tatef46723b2012-01-26 14:19:24 -080012774 synchronized(this) {
12775 ReceiverList rl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012776 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
Christopher Tatef46723b2012-01-26 14:19:24 -080012777 if (rl != null) {
12778 if (rl.curBroadcast != null) {
12779 BroadcastRecord r = rl.curBroadcast;
12780 final boolean doNext = finishReceiverLocked(
12781 receiver.asBinder(), r.resultCode, r.resultData,
12782 r.resultExtras, r.resultAbort, true);
12783 if (doNext) {
12784 doTrim = true;
12785 r.queue.processNextBroadcast(false);
12786 }
12787 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012788
Christopher Tatef46723b2012-01-26 14:19:24 -080012789 if (rl.app != null) {
12790 rl.app.receivers.remove(rl);
12791 }
12792 removeReceiverLocked(rl);
12793 if (rl.linkedToDeath) {
12794 rl.linkedToDeath = false;
12795 rl.receiver.asBinder().unlinkToDeath(rl, 0);
12796 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012797 }
12798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012799
Christopher Tatef46723b2012-01-26 14:19:24 -080012800 // If we actually concluded any broadcasts, we might now be able
12801 // to trim the recipients' apps from our working set
12802 if (doTrim) {
12803 trimApplications();
12804 return;
12805 }
12806
12807 } finally {
12808 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012809 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012810 }
12811
12812 void removeReceiverLocked(ReceiverList rl) {
12813 mRegisteredReceivers.remove(rl.receiver.asBinder());
12814 int N = rl.size();
12815 for (int i=0; i<N; i++) {
12816 mReceiverResolver.removeFilter(rl.get(i));
12817 }
12818 }
12819
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012820 private final void sendPackageBroadcastLocked(int cmd, String[] packages) {
12821 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12822 ProcessRecord r = mLruProcesses.get(i);
12823 if (r.thread != null) {
12824 try {
12825 r.thread.dispatchPackageBroadcast(cmd, packages);
12826 } catch (RemoteException ex) {
12827 }
12828 }
12829 }
12830 }
12831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012832 private final int broadcastIntentLocked(ProcessRecord callerApp,
12833 String callerPackage, Intent intent, String resolvedType,
12834 IIntentReceiver resultTo, int resultCode, String resultData,
12835 Bundle map, String requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070012836 boolean ordered, boolean sticky, int callingPid, int callingUid,
12837 int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012838 intent = new Intent(intent);
12839
Dianne Hackborne7f97212011-02-24 14:40:20 -080012840 // By default broadcasts do not go to stopped apps.
12841 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
12842
Joe Onorato8a9b2202010-02-26 18:56:32 -080012843 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012844 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
Amith Yamasani13593602012-03-22 16:16:17 -070012845 + " ordered=" + ordered + " userid=" + userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012846 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012847 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012848 }
12849
12850 // Handle special intents: if this broadcast is from the package
12851 // manager about a package being removed, we need to remove all of
12852 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012853 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012854 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012855 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
12856 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012857 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012858 || uidRemoved) {
12859 if (checkComponentPermission(
12860 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080012861 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012862 == PackageManager.PERMISSION_GRANTED) {
12863 if (uidRemoved) {
12864 final Bundle intentExtras = intent.getExtras();
12865 final int uid = intentExtras != null
12866 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
12867 if (uid >= 0) {
12868 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
12869 synchronized (bs) {
12870 bs.removeUidStatsLocked(uid);
12871 }
12872 }
12873 } else {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012874 // If resources are unvailble just force stop all
12875 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080012876 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012877 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
12878 if (list != null && (list.length > 0)) {
12879 for (String pkg : list) {
Amith Yamasani483f3b02012-03-13 16:08:00 -070012880 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012881 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012882 sendPackageBroadcastLocked(
12883 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080012884 }
12885 } else {
12886 Uri data = intent.getData();
12887 String ssp;
12888 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12889 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
12890 forceStopPackageLocked(ssp,
Amith Yamasani483f3b02012-03-13 16:08:00 -070012891 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
12892 false, userId);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070012893 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012894 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070012895 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
12896 new String[] {ssp});
12897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012898 }
12899 }
12900 }
12901 } else {
12902 String msg = "Permission Denial: " + intent.getAction()
12903 + " broadcast from " + callerPackage + " (pid=" + callingPid
12904 + ", uid=" + callingUid + ")"
12905 + " requires "
12906 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012907 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012908 throw new SecurityException(msg);
12909 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012910
12911 // Special case for adding a package: by default turn on compatibility
12912 // mode.
12913 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070012914 Uri data = intent.getData();
12915 String ssp;
12916 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
12917 mCompatModePackages.handlePackageAddedLocked(ssp,
12918 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070012919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012920 }
12921
12922 /*
12923 * If this is the time zone changed action, queue up a message that will reset the timezone
12924 * of all currently running processes. This message will get queued up before the broadcast
12925 * happens.
12926 */
12927 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
12928 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
12929 }
12930
Robert Greenwalt03595d02010-11-02 14:08:23 -070012931 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
12932 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
12933 }
12934
Robert Greenwalt434203a2010-10-11 16:00:27 -070012935 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
12936 ProxyProperties proxy = intent.getParcelableExtra("proxy");
12937 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
12938 }
12939
Dianne Hackborn854060af2009-07-09 18:14:31 -070012940 /*
12941 * Prevent non-system code (defined here to be non-persistent
12942 * processes) from sending protected broadcasts.
12943 */
12944 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
12945 || callingUid == Process.SHELL_UID || callingUid == 0) {
12946 // Always okay.
12947 } else if (callerApp == null || !callerApp.persistent) {
12948 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070012949 if (AppGlobals.getPackageManager().isProtectedBroadcast(
Dianne Hackborn854060af2009-07-09 18:14:31 -070012950 intent.getAction())) {
12951 String msg = "Permission Denial: not allowed to send broadcast "
12952 + intent.getAction() + " from pid="
12953 + callingPid + ", uid=" + callingUid;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012954 Slog.w(TAG, msg);
Dianne Hackborn854060af2009-07-09 18:14:31 -070012955 throw new SecurityException(msg);
12956 }
12957 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012958 Slog.w(TAG, "Remote exception", e);
Dianne Hackborna4972e92012-03-14 10:38:05 -070012959 return ActivityManager.BROADCAST_SUCCESS;
Dianne Hackborn854060af2009-07-09 18:14:31 -070012960 }
12961 }
12962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012963 // Add to the sticky list if requested.
12964 if (sticky) {
12965 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
12966 callingPid, callingUid)
12967 != PackageManager.PERMISSION_GRANTED) {
12968 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
12969 + callingPid + ", uid=" + callingUid
12970 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012971 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012972 throw new SecurityException(msg);
12973 }
12974 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012975 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012976 + " and enforce permission " + requiredPermission);
Dianne Hackborna4972e92012-03-14 10:38:05 -070012977 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012978 }
12979 if (intent.getComponent() != null) {
12980 throw new SecurityException(
12981 "Sticky broadcasts can't target a specific component");
12982 }
12983 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
12984 if (list == null) {
12985 list = new ArrayList<Intent>();
12986 mStickyBroadcasts.put(intent.getAction(), list);
12987 }
12988 int N = list.size();
12989 int i;
12990 for (i=0; i<N; i++) {
12991 if (intent.filterEquals(list.get(i))) {
12992 // This sticky already exists, replace it.
12993 list.set(i, new Intent(intent));
12994 break;
12995 }
12996 }
12997 if (i >= N) {
12998 list.add(new Intent(intent));
12999 }
13000 }
13001
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013002 // Figure out who all will receive this broadcast.
13003 List receivers = null;
13004 List<BroadcastFilter> registeredReceivers = null;
13005 try {
13006 if (intent.getComponent() != null) {
13007 // Broadcast is going to one specific receiver class...
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013008 ActivityInfo ai = AppGlobals.getPackageManager().
Amith Yamasani483f3b02012-03-13 16:08:00 -070013009 getReceiverInfo(intent.getComponent(), STOCK_PM_FLAGS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013010 if (ai != null) {
13011 receivers = new ArrayList();
13012 ResolveInfo ri = new ResolveInfo();
Amith Yamasania4a54e22012-04-16 15:44:19 -070013013 if (isSingleton(ai.processName, ai.applicationInfo)) {
13014 ri.activityInfo = getActivityInfoForUser(ai, 0);
13015 } else {
13016 ri.activityInfo = getActivityInfoForUser(ai, userId);
13017 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013018 receivers.add(ri);
13019 }
13020 } else {
13021 // Need to resolve the intent to interested receivers...
13022 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
13023 == 0) {
13024 receivers =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013025 AppGlobals.getPackageManager().queryIntentReceivers(
Amith Yamasani483f3b02012-03-13 16:08:00 -070013026 intent, resolvedType, STOCK_PM_FLAGS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013027 }
Amith Yamasani483f3b02012-03-13 16:08:00 -070013028 registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false,
13029 userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013030 }
13031 } catch (RemoteException ex) {
13032 // pm is in same process, this will never happen.
13033 }
13034
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013035 final boolean replacePending =
13036 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
13037
Joe Onorato8a9b2202010-02-26 18:56:32 -080013038 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013039 + " replacePending=" + replacePending);
13040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013041 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
13042 if (!ordered && NR > 0) {
13043 // If we are not serializing this broadcast, then send the
13044 // registered receivers separately so they don't wait for the
13045 // components to be launched.
Christopher Tatef46723b2012-01-26 14:19:24 -080013046 final BroadcastQueue queue = broadcastQueueForIntent(intent);
13047 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013048 callerPackage, callingPid, callingUid, requiredPermission,
13049 registeredReceivers, resultTo, resultCode, resultData, map,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013050 ordered, sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013051 if (DEBUG_BROADCAST) Slog.v(
Christopher Tatef46723b2012-01-26 14:19:24 -080013052 TAG, "Enqueueing parallel broadcast " + r);
13053 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013054 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013055 queue.enqueueParallelBroadcastLocked(r);
13056 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013058 registeredReceivers = null;
13059 NR = 0;
13060 }
13061
13062 // Merge into one list.
13063 int ir = 0;
13064 if (receivers != null) {
13065 // A special case for PACKAGE_ADDED: do not allow the package
13066 // being added to see this broadcast. This prevents them from
13067 // using this as a back door to get run as soon as they are
13068 // installed. Maybe in the future we want to have a special install
13069 // broadcast or such for apps, but we'd like to deliberately make
13070 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013071 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013072 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
13073 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
13074 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013075 Uri data = intent.getData();
13076 if (data != null) {
13077 String pkgName = data.getSchemeSpecificPart();
13078 if (pkgName != null) {
13079 skipPackages = new String[] { pkgName };
13080 }
13081 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070013082 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013083 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070013084 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080013085 if (skipPackages != null && (skipPackages.length > 0)) {
13086 for (String skipPackage : skipPackages) {
13087 if (skipPackage != null) {
13088 int NT = receivers.size();
13089 for (int it=0; it<NT; it++) {
13090 ResolveInfo curt = (ResolveInfo)receivers.get(it);
13091 if (curt.activityInfo.packageName.equals(skipPackage)) {
13092 receivers.remove(it);
13093 it--;
13094 NT--;
13095 }
13096 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013097 }
13098 }
13099 }
13100
13101 int NT = receivers != null ? receivers.size() : 0;
13102 int it = 0;
13103 ResolveInfo curt = null;
13104 BroadcastFilter curr = null;
13105 while (it < NT && ir < NR) {
13106 if (curt == null) {
13107 curt = (ResolveInfo)receivers.get(it);
13108 }
13109 if (curr == null) {
13110 curr = registeredReceivers.get(ir);
13111 }
13112 if (curr.getPriority() >= curt.priority) {
13113 // Insert this broadcast record into the final list.
13114 receivers.add(it, curr);
13115 ir++;
13116 curr = null;
13117 it++;
13118 NT++;
13119 } else {
13120 // Skip to the next ResolveInfo in the final list.
13121 it++;
13122 curt = null;
13123 }
13124 }
13125 }
13126 while (ir < NR) {
13127 if (receivers == null) {
13128 receivers = new ArrayList();
13129 }
13130 receivers.add(registeredReceivers.get(ir));
13131 ir++;
13132 }
13133
13134 if ((receivers != null && receivers.size() > 0)
13135 || resultTo != null) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013136 BroadcastQueue queue = broadcastQueueForIntent(intent);
13137 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080013139 receivers, resultTo, resultCode, resultData, map, ordered,
13140 sticky, false);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013141 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013142 TAG, "Enqueueing ordered broadcast " + r
Christopher Tatef46723b2012-01-26 14:19:24 -080013143 + ": prev had " + queue.mOrderedBroadcasts.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013144 if (DEBUG_BROADCAST) {
13145 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013146 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013147 }
Christopher Tatef46723b2012-01-26 14:19:24 -080013148 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013149 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013150 queue.enqueueOrderedBroadcastLocked(r);
13151 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013153 }
13154
Dianne Hackborna4972e92012-03-14 10:38:05 -070013155 return ActivityManager.BROADCAST_SUCCESS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013156 }
13157
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013158 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013159 // Refuse possible leaked file descriptors
13160 if (intent != null && intent.hasFileDescriptors() == true) {
13161 throw new IllegalArgumentException("File descriptors passed in Intent");
13162 }
13163
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013164 int flags = intent.getFlags();
13165
13166 if (!mProcessesReady) {
13167 // if the caller really truly claims to know what they're doing, go
13168 // ahead and allow the broadcast without launching any receivers
13169 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
13170 intent = new Intent(intent);
13171 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13172 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
13173 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
13174 + " before boot completion");
13175 throw new IllegalStateException("Cannot broadcast before boot completed");
13176 }
13177 }
13178
13179 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
13180 throw new IllegalArgumentException(
13181 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
13182 }
13183
13184 return intent;
13185 }
13186
13187 public final int broadcastIntent(IApplicationThread caller,
13188 Intent intent, String resolvedType, IIntentReceiver resultTo,
13189 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013190 String requiredPermission, boolean serialized, boolean sticky, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013191 enforceNotIsolatedCaller("broadcastIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013192 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013193 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070013194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013195 final ProcessRecord callerApp = getRecordForAppLocked(caller);
13196 final int callingPid = Binder.getCallingPid();
13197 final int callingUid = Binder.getCallingUid();
13198 final long origId = Binder.clearCallingIdentity();
13199 int res = broadcastIntentLocked(callerApp,
13200 callerApp != null ? callerApp.info.packageName : null,
13201 intent, resolvedType, resultTo,
Amith Yamasani742a6712011-05-04 14:49:28 -070013202 resultCode, resultData, map, requiredPermission, serialized, sticky,
13203 callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013204 Binder.restoreCallingIdentity(origId);
13205 return res;
13206 }
13207 }
13208
13209 int broadcastIntentInPackage(String packageName, int uid,
13210 Intent intent, String resolvedType, IIntentReceiver resultTo,
13211 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070013212 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013213 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070013214 intent = verifyBroadcastLocked(intent);
13215
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013216 final long origId = Binder.clearCallingIdentity();
13217 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
13218 resultTo, resultCode, resultData, map, requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070013219 serialized, sticky, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013220 Binder.restoreCallingIdentity(origId);
13221 return res;
13222 }
13223 }
13224
Amith Yamasani742a6712011-05-04 14:49:28 -070013225 // TODO: Use the userId; maybe mStickyBroadcasts need to be tied to the user.
13226 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013227 // Refuse possible leaked file descriptors
13228 if (intent != null && intent.hasFileDescriptors() == true) {
13229 throw new IllegalArgumentException("File descriptors passed in Intent");
13230 }
13231
13232 synchronized(this) {
13233 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
13234 != PackageManager.PERMISSION_GRANTED) {
13235 String msg = "Permission Denial: unbroadcastIntent() from pid="
13236 + Binder.getCallingPid()
13237 + ", uid=" + Binder.getCallingUid()
13238 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013239 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013240 throw new SecurityException(msg);
13241 }
13242 ArrayList<Intent> list = mStickyBroadcasts.get(intent.getAction());
13243 if (list != null) {
13244 int N = list.size();
13245 int i;
13246 for (i=0; i<N; i++) {
13247 if (intent.filterEquals(list.get(i))) {
13248 list.remove(i);
13249 break;
13250 }
13251 }
13252 }
13253 }
13254 }
13255
13256 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
13257 String resultData, Bundle resultExtras, boolean resultAbort,
13258 boolean explicit) {
Christopher Tatef46723b2012-01-26 14:19:24 -080013259 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
13260 if (r == null) {
13261 Slog.w(TAG, "finishReceiver called but not found on queue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013262 return false;
13263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013264
Christopher Tatef46723b2012-01-26 14:19:24 -080013265 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
13266 explicit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013267 }
13268
13269 public void finishReceiver(IBinder who, int resultCode, String resultData,
13270 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013271 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013272
13273 // Refuse possible leaked file descriptors
13274 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
13275 throw new IllegalArgumentException("File descriptors passed in Bundle");
13276 }
13277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013278 final long origId = Binder.clearCallingIdentity();
Christopher Tatef46723b2012-01-26 14:19:24 -080013279 try {
13280 boolean doNext = false;
13281 BroadcastRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013282
Christopher Tatef46723b2012-01-26 14:19:24 -080013283 synchronized(this) {
13284 r = broadcastRecordForReceiverLocked(who);
13285 if (r != null) {
13286 doNext = r.queue.finishReceiverLocked(r, resultCode,
13287 resultData, resultExtras, resultAbort, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013289 }
Jeff Brown4d94a762010-09-23 11:33:28 -070013290
Christopher Tatef46723b2012-01-26 14:19:24 -080013291 if (doNext) {
13292 r.queue.processNextBroadcast(false);
13293 }
13294 trimApplications();
13295 } finally {
13296 Binder.restoreCallingIdentity(origId);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070013297 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013298 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013299
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013300 // =========================================================
13301 // INSTRUMENTATION
13302 // =========================================================
13303
13304 public boolean startInstrumentation(ComponentName className,
13305 String profileFile, int flags, Bundle arguments,
13306 IInstrumentationWatcher watcher) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013307 enforceNotIsolatedCaller("startInstrumentation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013308 // Refuse possible leaked file descriptors
13309 if (arguments != null && arguments.hasFileDescriptors()) {
13310 throw new IllegalArgumentException("File descriptors passed in Bundle");
13311 }
13312
13313 synchronized(this) {
13314 InstrumentationInfo ii = null;
13315 ApplicationInfo ai = null;
13316 try {
13317 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070013318 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013319 ai = mContext.getPackageManager().getApplicationInfo(
Amith Yamasani483f3b02012-03-13 16:08:00 -070013320 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013321 } catch (PackageManager.NameNotFoundException e) {
13322 }
13323 if (ii == null) {
13324 reportStartInstrumentationFailure(watcher, className,
13325 "Unable to find instrumentation info for: " + className);
13326 return false;
13327 }
13328 if (ai == null) {
13329 reportStartInstrumentationFailure(watcher, className,
13330 "Unable to find instrumentation target package: " + ii.targetPackage);
13331 return false;
13332 }
13333
13334 int match = mContext.getPackageManager().checkSignatures(
13335 ii.targetPackage, ii.packageName);
13336 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
13337 String msg = "Permission Denial: starting instrumentation "
13338 + className + " from pid="
13339 + Binder.getCallingPid()
13340 + ", uid=" + Binder.getCallingPid()
13341 + " not allowed because package " + ii.packageName
13342 + " does not have a signature matching the target "
13343 + ii.targetPackage;
13344 reportStartInstrumentationFailure(watcher, className, msg);
13345 throw new SecurityException(msg);
13346 }
13347
Amith Yamasani483f3b02012-03-13 16:08:00 -070013348 int userId = UserId.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013349 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070013350 // Instrumentation can kill and relaunch even persistent processes
Amith Yamasani483f3b02012-03-13 16:08:00 -070013351 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013352 ProcessRecord app = addAppLocked(ai, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013353 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013354 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013355 app.instrumentationProfileFile = profileFile;
13356 app.instrumentationArguments = arguments;
13357 app.instrumentationWatcher = watcher;
13358 app.instrumentationResultClass = className;
13359 Binder.restoreCallingIdentity(origId);
13360 }
13361
13362 return true;
13363 }
13364
13365 /**
13366 * Report errors that occur while attempting to start Instrumentation. Always writes the
13367 * error to the logs, but if somebody is watching, send the report there too. This enables
13368 * the "am" command to report errors with more information.
13369 *
13370 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
13371 * @param cn The component name of the instrumentation.
13372 * @param report The error report.
13373 */
13374 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
13375 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013376 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013377 try {
13378 if (watcher != null) {
13379 Bundle results = new Bundle();
13380 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
13381 results.putString("Error", report);
13382 watcher.instrumentationStatus(cn, -1, results);
13383 }
13384 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013385 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013386 }
13387 }
13388
13389 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
13390 if (app.instrumentationWatcher != null) {
13391 try {
13392 // NOTE: IInstrumentationWatcher *must* be oneway here
13393 app.instrumentationWatcher.instrumentationFinished(
13394 app.instrumentationClass,
13395 resultCode,
13396 results);
13397 } catch (RemoteException e) {
13398 }
13399 }
13400 app.instrumentationWatcher = null;
13401 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070013402 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013403 app.instrumentationProfileFile = null;
13404 app.instrumentationArguments = null;
13405
Amith Yamasani483f3b02012-03-13 16:08:00 -070013406 forceStopPackageLocked(app.processName, -1, false, false, true, true, app.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013407 }
13408
13409 public void finishInstrumentation(IApplicationThread target,
13410 int resultCode, Bundle results) {
Amith Yamasani483f3b02012-03-13 16:08:00 -070013411 int userId = UserId.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013412 // Refuse possible leaked file descriptors
13413 if (results != null && results.hasFileDescriptors()) {
13414 throw new IllegalArgumentException("File descriptors passed in Intent");
13415 }
13416
13417 synchronized(this) {
13418 ProcessRecord app = getRecordForAppLocked(target);
13419 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013420 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013421 return;
13422 }
13423 final long origId = Binder.clearCallingIdentity();
13424 finishInstrumentationLocked(app, resultCode, results);
13425 Binder.restoreCallingIdentity(origId);
13426 }
13427 }
13428
13429 // =========================================================
13430 // CONFIGURATION
13431 // =========================================================
13432
13433 public ConfigurationInfo getDeviceConfigurationInfo() {
13434 ConfigurationInfo config = new ConfigurationInfo();
13435 synchronized (this) {
13436 config.reqTouchScreen = mConfiguration.touchscreen;
13437 config.reqKeyboardType = mConfiguration.keyboard;
13438 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013439 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
13440 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013441 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
13442 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070013443 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
13444 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013445 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
13446 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070013447 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013448 }
13449 return config;
13450 }
13451
13452 public Configuration getConfiguration() {
13453 Configuration ci;
13454 synchronized(this) {
13455 ci = new Configuration(mConfiguration);
13456 }
13457 return ci;
13458 }
13459
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013460 public void updatePersistentConfiguration(Configuration values) {
13461 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13462 "updateConfiguration()");
13463 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
13464 "updateConfiguration()");
13465 if (values == null) {
13466 throw new NullPointerException("Configuration must not be null");
13467 }
13468
13469 synchronized(this) {
13470 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080013471 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013472 Binder.restoreCallingIdentity(origId);
13473 }
13474 }
13475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013476 public void updateConfiguration(Configuration values) {
13477 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
13478 "updateConfiguration()");
13479
13480 synchronized(this) {
13481 if (values == null && mWindowManager != null) {
13482 // sentinel: fetch the current configuration from the window manager
13483 values = mWindowManager.computeNewConfiguration();
13484 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013485
13486 if (mWindowManager != null) {
13487 mProcessList.applyDisplaySize(mWindowManager);
13488 }
13489
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013490 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013491 if (values != null) {
13492 Settings.System.clearConfiguration(values);
13493 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080013494 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013495 Binder.restoreCallingIdentity(origId);
13496 }
13497 }
13498
13499 /**
13500 * Do either or both things: (1) change the current configuration, and (2)
13501 * make sure the given activity is running with the (now) current
13502 * configuration. Returns true if the activity has been left running, or
13503 * false if <var>starting</var> is being destroyed to match the new
13504 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013505 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013506 */
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013507 boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080013508 ActivityRecord starting, boolean persistent, boolean initLocale) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -070013509 // do nothing if we are headless
13510 if (mHeadless) return true;
13511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013512 int changes = 0;
13513
13514 boolean kept = true;
13515
13516 if (values != null) {
13517 Configuration newConfig = new Configuration(mConfiguration);
13518 changes = newConfig.updateFrom(values);
13519 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013520 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013521 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013522 }
13523
Doug Zongker2bec3d42009-12-04 12:52:44 -080013524 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013525
Dianne Hackborn813075a62011-11-14 17:45:19 -080013526 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013527 saveLocaleLocked(values.locale,
13528 !values.locale.equals(mConfiguration.locale),
13529 values.userSetLocale);
13530 }
13531
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013532 mConfigurationSeq++;
13533 if (mConfigurationSeq <= 0) {
13534 mConfigurationSeq = 1;
13535 }
13536 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013537 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080013538 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013539
13540 final Configuration configCopy = new Configuration(mConfiguration);
Joe Onorato54a4a412011-11-02 20:50:08 -070013541
13542 // TODO: If our config changes, should we auto dismiss any currently
13543 // showing dialogs?
13544 mShowDialogs = shouldShowDialogs(newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013545
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013546 AttributeCache ac = AttributeCache.instance();
13547 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080013548 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080013549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013550
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013551 // Make sure all resources in our process are updated
13552 // right now, so that anyone who is going to retrieve
13553 // resource values after we return will be sure to get
13554 // the new ones. This is especially important during
13555 // boot, where the first config change needs to guarantee
13556 // all resources have that config before following boot
13557 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080013558 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070013559
Dianne Hackborn31ca8542011-07-19 14:58:28 -070013560 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013561 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013562 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080013563 mHandler.sendMessage(msg);
13564 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013565
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013566 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13567 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013568 try {
13569 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013570 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070013571 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080013572 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013573 }
13574 } catch (Exception e) {
13575 }
13576 }
13577 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080013578 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13579 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013580 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013581 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013582 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
13583 broadcastIntentLocked(null, null,
13584 new Intent(Intent.ACTION_LOCALE_CHANGED),
13585 null, null, 0, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -070013586 null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080013587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013588 }
13589 }
13590
13591 if (changes != 0 && starting == null) {
13592 // If the configuration changed, and the caller is not already
13593 // in the process of starting an activity, then find the top
13594 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013595 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013596 }
13597
13598 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013599 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080013600 // And we need to make sure at this point that all other activities
13601 // are made visible with the correct configuration.
13602 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013603 }
13604
Dianne Hackborne36d6e22010-02-17 19:46:25 -080013605 if (values != null && mWindowManager != null) {
13606 mWindowManager.setNewConfiguration(mConfiguration);
13607 }
13608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013609 return kept;
13610 }
Joe Onorato54a4a412011-11-02 20:50:08 -070013611
13612 /**
13613 * Decide based on the configuration whether we should shouw the ANR,
13614 * crash, etc dialogs. The idea is that if there is no affordnace to
13615 * press the on-screen buttons, we shouldn't show the dialog.
13616 *
13617 * A thought: SystemUI might also want to get told about this, the Power
13618 * dialog / global actions also might want different behaviors.
13619 */
13620 private static final boolean shouldShowDialogs(Configuration config) {
13621 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
13622 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
13623 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013624
13625 /**
13626 * Save the locale. You must be inside a synchronized (this) block.
13627 */
13628 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
13629 if(isDiff) {
13630 SystemProperties.set("user.language", l.getLanguage());
13631 SystemProperties.set("user.region", l.getCountry());
13632 }
13633
13634 if(isPersist) {
13635 SystemProperties.set("persist.sys.language", l.getLanguage());
13636 SystemProperties.set("persist.sys.country", l.getCountry());
13637 SystemProperties.set("persist.sys.localevar", l.getVariant());
13638 }
13639 }
13640
Adam Powelldd8fab22012-03-22 17:47:27 -070013641 @Override
13642 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
13643 ActivityRecord srec = ActivityRecord.forToken(token);
Adam Powellb71a5bc2012-04-24 14:20:57 -070013644 return srec != null && srec.task.affinity != null &&
13645 srec.task.affinity.equals(destAffinity);
Adam Powelldd8fab22012-03-22 17:47:27 -070013646 }
13647
13648 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
13649 Intent resultData) {
13650 ComponentName dest = destIntent.getComponent();
13651
13652 synchronized (this) {
13653 ActivityRecord srec = ActivityRecord.forToken(token);
Adam Powellb71a5bc2012-04-24 14:20:57 -070013654 if (srec == null) {
13655 return false;
13656 }
Adam Powelldd8fab22012-03-22 17:47:27 -070013657 ArrayList<ActivityRecord> history = srec.stack.mHistory;
13658 final int start = history.indexOf(srec);
13659 if (start < 0) {
13660 // Current activity is not in history stack; do nothing.
13661 return false;
13662 }
13663 int finishTo = start - 1;
13664 ActivityRecord parent = null;
13665 boolean foundParentInTask = false;
13666 if (dest != null) {
13667 TaskRecord tr = srec.task;
13668 for (int i = start - 1; i >= 0; i--) {
13669 ActivityRecord r = history.get(i);
13670 if (tr != r.task) {
13671 // Couldn't find parent in the same task; stop at the one above this.
13672 // (Root of current task; in-app "home" behavior)
13673 // Always at least finish the current activity.
13674 finishTo = Math.min(start - 1, i + 1);
13675 parent = history.get(finishTo);
13676 break;
13677 } else if (r.info.packageName.equals(dest.getPackageName()) &&
13678 r.info.name.equals(dest.getClassName())) {
13679 finishTo = i;
13680 parent = r;
13681 foundParentInTask = true;
13682 break;
13683 }
13684 }
13685 }
13686
13687 if (mController != null) {
13688 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
13689 if (next != null) {
13690 // ask watcher if this is allowed
13691 boolean resumeOK = true;
13692 try {
13693 resumeOK = mController.activityResuming(next.packageName);
13694 } catch (RemoteException e) {
13695 mController = null;
13696 }
13697
13698 if (!resumeOK) {
13699 return false;
13700 }
13701 }
13702 }
13703 final long origId = Binder.clearCallingIdentity();
13704 for (int i = start; i > finishTo; i--) {
13705 ActivityRecord r = history.get(i);
13706 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
13707 "navigate-up");
13708 // Only return the supplied result for the first activity finished
13709 resultCode = Activity.RESULT_CANCELED;
13710 resultData = null;
13711 }
13712
13713 if (parent != null && foundParentInTask) {
13714 final int parentLaunchMode = parent.info.launchMode;
13715 final int destIntentFlags = destIntent.getFlags();
13716 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
13717 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
13718 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
13719 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
Adam Powell69de7e12012-05-07 18:42:24 -070013720 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
Adam Powelldd8fab22012-03-22 17:47:27 -070013721 } else {
13722 try {
13723 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
13724 destIntent.getComponent(), 0, UserId.getCallingUserId());
13725 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
13726 null, aInfo, parent.appToken, null,
13727 0, -1, parent.launchedFromUid, 0, null, true, null);
13728 foundParentInTask = res == ActivityManager.START_SUCCESS;
13729 } catch (RemoteException e) {
13730 foundParentInTask = false;
13731 }
13732 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
13733 resultData, "navigate-up");
13734 }
13735 }
13736 Binder.restoreCallingIdentity(origId);
13737 return foundParentInTask;
13738 }
13739 }
13740
Dianne Hackborn5320eb82012-05-18 12:05:04 -070013741 public int getLaunchedFromUid(IBinder activityToken) {
13742 ActivityRecord srec = ActivityRecord.forToken(activityToken);
13743 if (srec == null) {
13744 return -1;
13745 }
13746 return srec.launchedFromUid;
13747 }
13748
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013749 // =========================================================
13750 // LIFETIME MANAGEMENT
13751 // =========================================================
13752
Christopher Tatef46723b2012-01-26 14:19:24 -080013753 // Returns which broadcast queue the app is the current [or imminent] receiver
13754 // on, or 'null' if the app is not an active broadcast recipient.
13755 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
13756 BroadcastRecord r = app.curReceiver;
13757 if (r != null) {
13758 return r.queue;
13759 }
13760
13761 // It's not the current receiver, but it might be starting up to become one
13762 synchronized (this) {
13763 for (BroadcastQueue queue : mBroadcastQueues) {
13764 r = queue.mPendingBroadcast;
13765 if (r != null && r.curApp == app) {
13766 // found it; report which queue it's in
13767 return queue;
13768 }
13769 }
13770 }
13771
13772 return null;
13773 }
13774
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013775 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013776 ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013777 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013778 // This adjustment has already been computed. If we are calling
13779 // from the top, we may have already computed our adjustment with
13780 // an earlier hidden adjustment that isn't really for us... if
13781 // so, use the new hidden adjustment.
13782 if (!recursed && app.hidden) {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013783 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013784 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013785 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013786 }
13787
13788 if (app.thread == null) {
13789 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013790 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013791 return (app.curAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013792 }
13793
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013794 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
13795 app.adjSource = null;
13796 app.adjTarget = null;
13797 app.empty = false;
13798 app.hidden = false;
13799
13800 final int activitiesSize = app.activities.size();
13801
Dianne Hackborn7d608422011-08-07 16:24:18 -070013802 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013803 // The max adjustment doesn't allow this app to be anything
13804 // below foreground, so it is not worth doing work for it.
13805 app.adjType = "fixed";
13806 app.adjSeq = mAdjSeq;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013807 app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013808 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013809 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013810 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013811 // System process can do UI, and when they do we want to have
13812 // them trim their memory after the user leaves the UI. To
13813 // facilitate this, here we need to determine whether or not it
13814 // is currently showing UI.
13815 app.systemNoUi = true;
13816 if (app == TOP_APP) {
13817 app.systemNoUi = false;
13818 } else if (activitiesSize > 0) {
13819 for (int j = 0; j < activitiesSize; j++) {
13820 final ActivityRecord r = app.activities.get(j);
13821 if (r.visible) {
13822 app.systemNoUi = false;
13823 break;
13824 }
13825 }
13826 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013827 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013828 }
13829
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013830 app.keeping = false;
13831 app.systemNoUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013832
The Android Open Source Project4df24232009-03-05 14:34:35 -080013833 // Determine the importance of the process, starting with most
13834 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013835 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013836 int schedGroup;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013837 boolean foregroundActivities = false;
13838 boolean interesting = false;
Christopher Tatef46723b2012-01-26 14:19:24 -080013839 BroadcastQueue queue;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013840 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013841 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013842 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013843 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013844 app.adjType = "top-activity";
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013845 foregroundActivities = true;
13846 interesting = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013847 } else if (app.instrumentationClass != null) {
13848 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013849 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013850 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013851 app.adjType = "instrumentation";
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013852 interesting = true;
Christopher Tatef46723b2012-01-26 14:19:24 -080013853 } else if ((queue = isReceivingBroadcast(app)) != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013854 // An app that is currently receiving a broadcast also
Christopher Tatef46723b2012-01-26 14:19:24 -080013855 // counts as being in the foreground for OOM killer purposes.
13856 // It's placed in a sched group based on the nature of the
13857 // broadcast as reflected by which queue it's active in.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013858 adj = ProcessList.FOREGROUND_APP_ADJ;
Christopher Tatef46723b2012-01-26 14:19:24 -080013859 schedGroup = (queue == mFgBroadcastQueue)
13860 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013861 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013862 } else if (app.executingServices.size() > 0) {
13863 // An app that is currently executing a service callback also
13864 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013865 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013866 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013867 app.adjType = "exec-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013868 } else if (activitiesSize > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013869 // This app is in the background with paused activities.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013870 // We inspect activities to potentially upgrade adjustment further below.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013871 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013872 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013873 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013874 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013875 } else {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013876 // A very not-needed process. If this is lower in the lru list,
13877 // we will push it in to the empty bucket.
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013878 adj = hiddenAdj;
13879 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013880 app.hidden = true;
13881 app.empty = true;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013882 app.adjType = "bg-empty";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013883 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013884
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013885 boolean hasStoppingActivities = false;
13886
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013887 // Examine all activities if not already foreground.
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013888 if (!foregroundActivities && activitiesSize > 0) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013889 for (int j = 0; j < activitiesSize; j++) {
13890 final ActivityRecord r = app.activities.get(j);
13891 if (r.visible) {
13892 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013893 if (adj > ProcessList.VISIBLE_APP_ADJ) {
13894 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013895 app.adjType = "visible";
13896 }
13897 schedGroup = Process.THREAD_GROUP_DEFAULT;
13898 app.hidden = false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013899 foregroundActivities = true;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013900 break;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013901 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013902 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13903 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013904 app.adjType = "pausing";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013905 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080013906 app.hidden = false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013907 foregroundActivities = true;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013908 } else if (r.state == ActivityState.STOPPING) {
13909 // We will apply the actual adjustment later, because
13910 // we want to allow this process to immediately go through
13911 // any memory trimming that is in effect.
13912 app.hidden = false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013913 foregroundActivities = true;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013914 hasStoppingActivities = true;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013915 }
13916 }
13917 }
13918
Dianne Hackborn7d608422011-08-07 16:24:18 -070013919 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013920 if (app.foregroundServices) {
13921 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013922 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013923 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013924 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013925 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013926 } else if (app.forcingToForeground != null) {
13927 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013928 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013929 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013930 app.adjType = "force-foreground";
13931 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013932 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013933 }
13934 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013935
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013936 if (app.foregroundServices) {
13937 interesting = true;
13938 }
13939
Dianne Hackborn7d608422011-08-07 16:24:18 -070013940 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013941 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013942 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013943 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013944 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013945 app.adjType = "heavy";
13946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013947
Dianne Hackborn7d608422011-08-07 16:24:18 -070013948 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013949 // This process is hosting what we currently consider to be the
13950 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013951 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013952 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013953 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080013954 app.adjType = "home";
13955 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013956
Dianne Hackbornf35fe232011-11-01 19:25:20 -070013957 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
13958 && app.activities.size() > 0) {
13959 // This was the previous process that showed UI to the user.
13960 // We want to try to keep it around more aggressively, to give
13961 // a good experience around switching between two apps.
13962 adj = ProcessList.PREVIOUS_APP_ADJ;
13963 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
13964 app.hidden = false;
13965 app.adjType = "previous";
13966 }
13967
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013968 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
13969 + " reason=" + app.adjType);
13970
The Android Open Source Project4df24232009-03-05 14:34:35 -080013971 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013972 // there are applications dependent on our services or providers, but
13973 // this gives us a baseline and makes sure we don't get into an
13974 // infinite recursion.
13975 app.adjSeq = mAdjSeq;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013976 app.curRawAdj = app.nonStoppingAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013977
Christopher Tate6fa95972009-06-05 18:43:55 -070013978 if (mBackupTarget != null && app == mBackupTarget.app) {
13979 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070013980 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013981 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013982 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013983 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013984 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070013985 }
13986 }
13987
Dianne Hackborn7d608422011-08-07 16:24:18 -070013988 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013989 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013990 final long now = SystemClock.uptimeMillis();
13991 // This process is more important if the top activity is
13992 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070013993 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013994 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013995 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013996 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070013997 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070013998 // If this process has shown some UI, let it immediately
13999 // go to the LRU list because it may be pretty heavy with
14000 // UI stuff. We'll tag it with a label just to help
14001 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014002 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014003 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014004 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014005 } else {
14006 if (now < (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14007 // This service has seen some activity within
14008 // recent memory, so we will keep its process ahead
14009 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014010 if (adj > ProcessList.SERVICE_ADJ) {
14011 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014012 app.adjType = "started-services";
14013 app.hidden = false;
14014 }
14015 }
14016 // If we have let the service slide into the background
14017 // state, still have some text describing what it is doing
14018 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014019 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070014020 app.adjType = "started-bg-services";
14021 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014022 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014023 // Don't kill this process because it is doing work; it
14024 // has said it is doing work.
14025 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014026 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014027 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014028 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014029 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014030 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014031 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014032 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014033 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014034 // XXX should compute this based on the max of
14035 // all connected clients.
14036 ConnectionRecord cr = clist.get(i);
14037 if (cr.binding.client == app) {
14038 // Binding to ourself is not interesting.
14039 continue;
14040 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014041 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014042 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014043 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014044 int myHiddenAdj = hiddenAdj;
14045 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014046 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014047 myHiddenAdj = client.hiddenAdj;
14048 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014049 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014050 }
14051 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014052 clientAdj = computeOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014053 client, myHiddenAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014054 String adjType = null;
14055 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
14056 // Not doing bind OOM management, so treat
14057 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014058 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014059 // If this process has shown some UI, let it immediately
14060 // go to the LRU list because it may be pretty heavy with
14061 // UI stuff. We'll tag it with a label just to help
14062 // debug and understand what is going on.
14063 if (adj > clientAdj) {
14064 adjType = "bound-bg-ui-services";
14065 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014066 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014067 clientAdj = adj;
14068 } else {
14069 if (now >= (s.lastActivity+MAX_SERVICE_INACTIVITY)) {
14070 // This service has not seen activity within
14071 // recent memory, so allow it to drop to the
14072 // LRU list if there is no other reason to keep
14073 // it around. We'll also tag it with a label just
14074 // to help debug and undertand what is going on.
14075 if (adj > clientAdj) {
14076 adjType = "bound-bg-services";
14077 }
14078 clientAdj = adj;
14079 }
14080 }
14081 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014082 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014083 // If this process has recently shown UI, and
14084 // the process that is binding to it is less
14085 // important than being visible, then we don't
14086 // care about the binding as much as we care
14087 // about letting this process get into the LRU
14088 // list to be killed and restarted if needed for
14089 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070014090 if (app.hasShownUi && app != mHomeProcess
14091 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014092 adjType = "bound-bg-ui-services";
14093 } else {
14094 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
14095 |Context.BIND_IMPORTANT)) != 0) {
14096 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014097 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
14098 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
14099 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14100 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14101 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014102 adj = clientAdj;
14103 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070014104 app.pendingUiClean = true;
14105 if (adj > ProcessList.VISIBLE_APP_ADJ) {
14106 adj = ProcessList.VISIBLE_APP_ADJ;
14107 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014108 }
14109 if (!client.hidden) {
14110 app.hidden = false;
14111 }
14112 if (client.keeping) {
14113 app.keeping = true;
14114 }
14115 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014116 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014117 }
14118 if (adjType != null) {
14119 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014120 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14121 .REASON_SERVICE_IN_USE;
14122 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014123 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070014124 app.adjTarget = s.name;
14125 }
14126 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14127 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14128 schedGroup = Process.THREAD_GROUP_DEFAULT;
14129 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014130 }
14131 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014132 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
14133 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014134 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014135 (a.visible || a.state == ActivityState.RESUMED
14136 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014137 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014138 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
14139 schedGroup = Process.THREAD_GROUP_DEFAULT;
14140 }
14141 app.hidden = false;
14142 app.adjType = "service";
14143 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14144 .REASON_SERVICE_IN_USE;
14145 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070014146 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014147 app.adjTarget = s.name;
14148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014150 }
14151 }
14152 }
14153 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014154
Dianne Hackborn287952c2010-09-22 22:34:31 -070014155 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014156 // would like to avoid killing it unless it would prevent the current
14157 // application from running. By default we put the process in
14158 // with the rest of the background processes; as we scan through
14159 // its services we may bump it up from there.
14160 if (adj > hiddenAdj) {
14161 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014162 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070014163 app.adjType = "bg-services";
14164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014165 }
14166
Dianne Hackborn7d608422011-08-07 16:24:18 -070014167 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014168 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014169 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014170 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014171 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070014172 ContentProviderRecord cpr = jt.next();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070014173 for (int i = cpr.connections.size()-1;
14174 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
14175 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
14176 i--) {
14177 ContentProviderConnection conn = cpr.connections.get(i);
14178 ProcessRecord client = conn.client;
14179 if (client == app) {
14180 // Being our own client is not interesting.
14181 continue;
14182 }
14183 int myHiddenAdj = hiddenAdj;
14184 if (myHiddenAdj > client.hiddenAdj) {
14185 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
14186 myHiddenAdj = client.hiddenAdj;
14187 } else {
14188 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project10592532009-03-18 17:39:46 -070014189 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070014190 }
14191 int clientAdj = computeOomAdjLocked(
14192 client, myHiddenAdj, TOP_APP, true, doingAll);
14193 if (adj > clientAdj) {
14194 if (app.hasShownUi && app != mHomeProcess
14195 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14196 app.adjType = "bg-ui-provider";
14197 } else {
14198 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
14199 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
14200 app.adjType = "provider";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014201 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070014202 if (!client.hidden) {
14203 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014204 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070014205 if (client.keeping) {
14206 app.keeping = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014207 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070014208 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
14209 .REASON_PROVIDER_IN_USE;
14210 app.adjSource = client;
14211 app.adjSourceOom = clientAdj;
14212 app.adjTarget = cpr.name;
14213 }
14214 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
14215 schedGroup = Process.THREAD_GROUP_DEFAULT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014216 }
14217 }
14218 // If the provider has external (non-framework) process
14219 // dependencies, ensure that its adjustment is at least
14220 // FOREGROUND_APP_ADJ.
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080014221 if (cpr.hasExternalProcessHandles()) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014222 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
14223 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014224 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014225 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014226 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070014227 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070014228 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014229 }
14230 }
14231 }
14232 }
14233
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014234 if (adj == ProcessList.SERVICE_ADJ) {
14235 if (doingAll) {
14236 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
14237 mNewNumServiceProcs++;
14238 }
14239 if (app.serviceb) {
14240 adj = ProcessList.SERVICE_B_ADJ;
14241 }
14242 } else {
14243 app.serviceb = false;
14244 }
14245
14246 app.nonStoppingAdj = adj;
14247
14248 if (hasStoppingActivities) {
14249 // Only upgrade adjustment.
14250 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
14251 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14252 app.adjType = "stopping";
14253 }
14254 }
14255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014256 app.curRawAdj = adj;
14257
Joe Onorato8a9b2202010-02-26 18:56:32 -080014258 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014259 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
14260 if (adj > app.maxAdj) {
14261 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014262 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080014263 schedGroup = Process.THREAD_GROUP_DEFAULT;
14264 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014265 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070014266 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014267 app.keeping = true;
14268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014269
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014270 if (app.hasAboveClient) {
14271 // If this process has bound to any services with BIND_ABOVE_CLIENT,
14272 // then we need to drop its adjustment to be lower than the service's
14273 // in order to honor the request. We want to drop it by one adjustment
14274 // level... but there is special meaning applied to various levels so
14275 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014276 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014277 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070014278 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
14279 adj = ProcessList.VISIBLE_APP_ADJ;
14280 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
14281 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
14282 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
14283 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014284 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014285 adj++;
14286 }
14287 }
14288
Dianne Hackborna93c2c12012-05-31 15:29:36 -070014289 int importance = app.memImportance;
14290 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
14291 app.curAdj = adj;
14292 app.curSchedGroup = schedGroup;
14293 if (!interesting) {
14294 // For this reporting, if there is not something explicitly
14295 // interesting in this process then we will push it to the
14296 // background importance.
14297 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14298 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
14299 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14300 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
14301 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14302 } else if (adj >= ProcessList.HOME_APP_ADJ) {
14303 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
14304 } else if (adj >= ProcessList.SERVICE_ADJ) {
14305 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
14306 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
14307 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
14308 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
14309 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
14310 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
14311 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
14312 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
14313 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
14314 } else {
14315 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
14316 }
14317 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014318
Dianne Hackborna93c2c12012-05-31 15:29:36 -070014319 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
14320 if (foregroundActivities != app.foregroundActivities) {
14321 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
14322 }
14323 if (changes != 0) {
14324 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
14325 app.memImportance = importance;
14326 app.foregroundActivities = foregroundActivities;
14327 int i = mPendingProcessChanges.size()-1;
14328 ProcessChangeItem item = null;
14329 while (i >= 0) {
14330 item = mPendingProcessChanges.get(i);
14331 if (item.pid == app.pid) {
14332 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
14333 break;
14334 }
14335 i--;
14336 }
14337 if (i < 0) {
14338 // No existing item in pending changes; need a new one.
14339 final int NA = mAvailProcessChanges.size();
14340 if (NA > 0) {
14341 item = mAvailProcessChanges.remove(NA-1);
14342 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
14343 } else {
14344 item = new ProcessChangeItem();
14345 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
14346 }
14347 item.changes = 0;
14348 item.pid = app.pid;
14349 item.uid = app.info.uid;
14350 if (mPendingProcessChanges.size() == 0) {
14351 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
14352 "*** Enqueueing dispatch processes changed!");
14353 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
14354 }
14355 mPendingProcessChanges.add(item);
14356 }
14357 item.changes |= changes;
14358 item.importance = importance;
14359 item.foregroundActivities = foregroundActivities;
14360 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
14361 + Integer.toHexString(System.identityHashCode(item))
14362 + " " + app.toShortString() + ": changes=" + item.changes
14363 + " importance=" + item.importance
14364 + " foreground=" + item.foregroundActivities
14365 + " type=" + app.adjType + " source=" + app.adjSource
14366 + " target=" + app.adjTarget);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070014367 }
14368
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014369 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014370 }
14371
14372 /**
14373 * Ask a given process to GC right now.
14374 */
14375 final void performAppGcLocked(ProcessRecord app) {
14376 try {
14377 app.lastRequestedGc = SystemClock.uptimeMillis();
14378 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014379 if (app.reportLowMemory) {
14380 app.reportLowMemory = false;
14381 app.thread.scheduleLowMemory();
14382 } else {
14383 app.thread.processInBackground();
14384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014385 }
14386 } catch (Exception e) {
14387 // whatever.
14388 }
14389 }
14390
14391 /**
14392 * Returns true if things are idle enough to perform GCs.
14393 */
Josh Bartel7f208742010-02-25 11:01:44 -060014394 private final boolean canGcNowLocked() {
Christopher Tatef46723b2012-01-26 14:19:24 -080014395 boolean processingBroadcasts = false;
14396 for (BroadcastQueue q : mBroadcastQueues) {
14397 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
14398 processingBroadcasts = true;
14399 }
14400 }
14401 return !processingBroadcasts
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014402 && (mSleeping || (mMainStack.mResumedActivity != null &&
14403 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014404 }
14405
14406 /**
14407 * Perform GCs on all processes that are waiting for it, but only
14408 * if things are idle.
14409 */
14410 final void performAppGcsLocked() {
14411 final int N = mProcessesToGc.size();
14412 if (N <= 0) {
14413 return;
14414 }
Josh Bartel7f208742010-02-25 11:01:44 -060014415 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014416 while (mProcessesToGc.size() > 0) {
14417 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014418 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014419 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
14420 <= SystemClock.uptimeMillis()) {
14421 // To avoid spamming the system, we will GC processes one
14422 // at a time, waiting a few seconds between each.
14423 performAppGcLocked(proc);
14424 scheduleAppGcsLocked();
14425 return;
14426 } else {
14427 // It hasn't been long enough since we last GCed this
14428 // process... put it in the list to wait for its time.
14429 addProcessToGcListLocked(proc);
14430 break;
14431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014432 }
14433 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014434
14435 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014436 }
14437 }
14438
14439 /**
14440 * If all looks good, perform GCs on all processes waiting for them.
14441 */
14442 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060014443 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014444 performAppGcsLocked();
14445 return;
14446 }
14447 // Still not idle, wait some more.
14448 scheduleAppGcsLocked();
14449 }
14450
14451 /**
14452 * Schedule the execution of all pending app GCs.
14453 */
14454 final void scheduleAppGcsLocked() {
14455 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014456
14457 if (mProcessesToGc.size() > 0) {
14458 // Schedule a GC for the time to the next process.
14459 ProcessRecord proc = mProcessesToGc.get(0);
14460 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
14461
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014462 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014463 long now = SystemClock.uptimeMillis();
14464 if (when < (now+GC_TIMEOUT)) {
14465 when = now + GC_TIMEOUT;
14466 }
14467 mHandler.sendMessageAtTime(msg, when);
14468 }
14469 }
14470
14471 /**
14472 * Add a process to the array of processes waiting to be GCed. Keeps the
14473 * list in sorted order by the last GC time. The process can't already be
14474 * on the list.
14475 */
14476 final void addProcessToGcListLocked(ProcessRecord proc) {
14477 boolean added = false;
14478 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
14479 if (mProcessesToGc.get(i).lastRequestedGc <
14480 proc.lastRequestedGc) {
14481 added = true;
14482 mProcessesToGc.add(i+1, proc);
14483 break;
14484 }
14485 }
14486 if (!added) {
14487 mProcessesToGc.add(0, proc);
14488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014489 }
14490
14491 /**
14492 * Set up to ask a process to GC itself. This will either do it
14493 * immediately, or put it on the list of processes to gc the next
14494 * time things are idle.
14495 */
14496 final void scheduleAppGcLocked(ProcessRecord app) {
14497 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014498 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014499 return;
14500 }
14501 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070014502 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014503 scheduleAppGcsLocked();
14504 }
14505 }
14506
Dianne Hackborn287952c2010-09-22 22:34:31 -070014507 final void checkExcessivePowerUsageLocked(boolean doKills) {
14508 updateCpuStatsNow();
14509
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014510 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014511 boolean doWakeKills = doKills;
14512 boolean doCpuKills = doKills;
14513 if (mLastPowerCheckRealtime == 0) {
14514 doWakeKills = false;
14515 }
14516 if (mLastPowerCheckUptime == 0) {
14517 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014518 }
14519 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070014520 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014521 }
14522 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070014523 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
14524 final long curUptime = SystemClock.uptimeMillis();
14525 final long uptimeSince = curUptime - mLastPowerCheckUptime;
14526 mLastPowerCheckRealtime = curRealtime;
14527 mLastPowerCheckUptime = curUptime;
14528 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
14529 doWakeKills = false;
14530 }
14531 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
14532 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014533 }
14534 int i = mLruProcesses.size();
14535 while (i > 0) {
14536 i--;
14537 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014538 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014539 long wtime;
14540 synchronized (stats) {
14541 wtime = stats.getProcessWakeTime(app.info.uid,
14542 app.pid, curRealtime);
14543 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070014544 long wtimeUsed = wtime - app.lastWakeTime;
14545 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
14546 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014547 StringBuilder sb = new StringBuilder(128);
14548 sb.append("Wake for ");
14549 app.toShortString(sb);
14550 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014551 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014552 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014553 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014554 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070014555 sb.append((wtimeUsed*100)/realtimeSince);
14556 sb.append("%)");
14557 Slog.i(TAG, sb.toString());
14558 sb.setLength(0);
14559 sb.append("CPU for ");
14560 app.toShortString(sb);
14561 sb.append(": over ");
14562 TimeUtils.formatDuration(uptimeSince, sb);
14563 sb.append(" used ");
14564 TimeUtils.formatDuration(cputimeUsed, sb);
14565 sb.append(" (");
14566 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070014567 sb.append("%)");
14568 Slog.i(TAG, sb.toString());
14569 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014570 // If a process has held a wake lock for more
14571 // than 50% of the time during this period,
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014572 // that sounds bad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070014573 if (doWakeKills && realtimeSince > 0
14574 && ((wtimeUsed*100)/realtimeSince) >= 50) {
14575 synchronized (stats) {
14576 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
14577 realtimeSince, wtimeUsed);
14578 }
14579 Slog.w(TAG, "Excessive wake lock in " + app.processName
14580 + " (pid " + app.pid + "): held " + wtimeUsed
14581 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014582 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14583 app.processName, app.setAdj, "excessive wake lock");
14584 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070014585 } else if (doCpuKills && uptimeSince > 0
14586 && ((cputimeUsed*100)/uptimeSince) >= 50) {
14587 synchronized (stats) {
14588 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
14589 uptimeSince, cputimeUsed);
14590 }
14591 Slog.w(TAG, "Excessive CPU in " + app.processName
14592 + " (pid " + app.pid + "): used " + cputimeUsed
14593 + " during " + uptimeSince);
14594 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14595 app.processName, app.setAdj, "excessive cpu");
14596 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014597 } else {
14598 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070014599 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014600 }
14601 }
14602 }
14603 }
14604
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014605 private final boolean updateOomAdjLocked(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014606 ProcessRecord app, int hiddenAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014607 app.hiddenAdj = hiddenAdj;
14608
14609 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014610 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014611 }
14612
Dianne Hackborn287952c2010-09-22 22:34:31 -070014613 final boolean wasKeeping = app.keeping;
14614
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014615 boolean success = true;
14616
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014617 computeOomAdjLocked(app, hiddenAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014618
Jeff Brown10e89712011-07-08 18:52:57 -070014619 if (app.curRawAdj != app.setRawAdj) {
Jeff Brown10e89712011-07-08 18:52:57 -070014620 if (wasKeeping && !app.keeping) {
14621 // This app is no longer something we want to keep. Note
14622 // its current wake lock time to later know to kill it if
14623 // it is not behaving well.
14624 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
14625 synchronized (stats) {
14626 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
14627 app.pid, SystemClock.elapsedRealtime());
14628 }
14629 app.lastCpuTime = app.curCpuTime;
14630 }
14631
14632 app.setRawAdj = app.curRawAdj;
14633 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014634
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014635 if (app.curAdj != app.setAdj) {
14636 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080014637 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014638 TAG, "Set " + app.pid + " " + app.processName +
14639 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014640 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070014641 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014642 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014643 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070014644 }
14645 }
14646 if (app.setSchedGroup != app.curSchedGroup) {
14647 app.setSchedGroup = app.curSchedGroup;
14648 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
14649 "Setting process group of " + app.processName
14650 + " to " + app.curSchedGroup);
14651 if (app.waitingToKill != null &&
14652 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
14653 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
14654 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14655 app.processName, app.setAdj, app.waitingToKill);
Dianne Hackborn45a25bc2012-06-28 13:49:17 -070014656 app.killedBackground = true;
Jeff Brown10e89712011-07-08 18:52:57 -070014657 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014658 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070014659 } else {
14660 if (true) {
14661 long oldId = Binder.clearCallingIdentity();
14662 try {
14663 Process.setProcessGroup(app.pid, app.curSchedGroup);
14664 } catch (Exception e) {
14665 Slog.w(TAG, "Failed setting process group of " + app.pid
14666 + " to " + app.curSchedGroup);
14667 e.printStackTrace();
14668 } finally {
14669 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070014670 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014671 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070014672 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014673 try {
Jeff Brown10e89712011-07-08 18:52:57 -070014674 app.thread.setSchedulingGroup(app.curSchedGroup);
14675 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070014676 }
14677 }
14678 }
14679 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014680 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014681 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014682 }
14683
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014684 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014685 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014686 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -080014687 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014688 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014689 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014690 }
14691 }
14692 return resumedActivity;
14693 }
14694
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014695 private final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014696 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014697 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14698 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070014699 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14700 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014701
14702 mAdjSeq++;
14703
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014704 boolean success = updateOomAdjLocked(app, app.hiddenAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070014705 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
14706 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014707 if (nowHidden != wasHidden) {
14708 // Changed to/from hidden state, so apps after it in the LRU
14709 // list may also be changed.
14710 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014711 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070014712 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014713 }
14714
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014715 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070014716 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014717 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
14718
14719 if (false) {
14720 RuntimeException e = new RuntimeException();
14721 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080014722 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014723 }
14724
14725 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014726 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014727
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014728 // Let's determine how many processes we have running vs.
14729 // how many slots we have for background processes; we may want
14730 // to put multiple processes in a slot of there are enough of
14731 // them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014732 int numSlots = ProcessList.HIDDEN_APP_MAX_ADJ - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014733 int factor = (mLruProcesses.size()-4)/numSlots;
14734 if (factor < 1) factor = 1;
14735 int step = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070014736 int numHidden = 0;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014737 int numTrimming = 0;
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080014738
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014739 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014740 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014741 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070014742 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014743 while (i > 0) {
14744 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014745 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080014746 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014747 updateOomAdjLocked(app, curHiddenAdj, TOP_APP, true);
14748 if (curHiddenAdj < ProcessList.HIDDEN_APP_MAX_ADJ
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014749 && app.curAdj == curHiddenAdj) {
14750 step++;
14751 if (step >= factor) {
14752 step = 0;
14753 curHiddenAdj++;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014754 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014755 }
14756 if (!app.killedBackground) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070014757 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014758 numHidden++;
14759 if (numHidden > mProcessLimit) {
14760 Slog.i(TAG, "No longer want " + app.processName
14761 + " (pid " + app.pid + "): hidden #" + numHidden);
14762 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14763 app.processName, app.setAdj, "too many background");
14764 app.killedBackground = true;
14765 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070014766 }
14767 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -080014768 if (!app.killedBackground && app.isolated && app.services.size() <= 0) {
14769 // If this is an isolated process, and there are no
14770 // services running in it, then the process is no longer
14771 // needed. We agressively kill these because we can by
14772 // definition not re-use the same process again, and it is
14773 // good to avoid having whatever code was running in them
14774 // left sitting around after no longer needed.
14775 Slog.i(TAG, "Isolated process " + app.processName
14776 + " (pid " + app.pid + ") no longer needed");
14777 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14778 app.processName, app.setAdj, "isolated not needed");
14779 app.killedBackground = true;
14780 Process.killProcessQuiet(app.pid);
14781 }
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014782 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14783 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
14784 && !app.killedBackground) {
14785 numTrimming++;
14786 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014787 }
14788 }
14789
Dianne Hackborne02c88a2011-10-28 13:58:15 -070014790 mNumServiceProcs = mNewNumServiceProcs;
14791
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014792 // Now determine the memory trimming level of background processes.
14793 // Unfortunately we need to start at the back of the list to do this
14794 // properly. We only do this if the number of background apps we
14795 // are managing to keep around is less than half the maximum we desire;
14796 // if we are keeping a good number around, we'll let them use whatever
14797 // memory they want.
Dianne Hackborn7d608422011-08-07 16:24:18 -070014798 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014799 final int N = mLruProcesses.size();
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014800 factor = numTrimming/3;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014801 int minFactor = 2;
14802 if (mHomeProcess != null) minFactor++;
14803 if (mPreviousProcess != null) minFactor++;
14804 if (factor < minFactor) factor = minFactor;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014805 step = 0;
Dianne Hackborn27ff9132012-03-06 14:57:58 -080014806 int fgTrimLevel;
14807 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/5)) {
14808 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
14809 } else if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/3)) {
14810 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
14811 } else {
14812 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
14813 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014814 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014815 for (i=0; i<N; i++) {
14816 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014817 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
14818 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080014819 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014820 if (app.trimMemoryLevel < curLevel && app.thread != null) {
14821 try {
14822 app.thread.scheduleTrimMemory(curLevel);
14823 } catch (RemoteException e) {
14824 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014825 if (false) {
14826 // For now we won't do this; our memory trimming seems
14827 // to be good enough at this point that destroying
14828 // activities causes more harm than good.
14829 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
14830 && app != mHomeProcess && app != mPreviousProcess) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070014831 // Need to do this on its own message because the stack may not
14832 // be in a consistent state at this point.
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014833 // For these apps we will also finish their activities
14834 // to help them free memory.
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070014835 mMainStack.scheduleDestroyActivities(app, false, "trim");
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080014836 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014837 }
14838 }
14839 app.trimMemoryLevel = curLevel;
14840 step++;
14841 if (step >= factor) {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080014842 step = 0;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014843 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014844 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
14845 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014846 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014847 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
14848 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014849 break;
14850 }
14851 }
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014852 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014853 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014854 && app.thread != null) {
14855 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014856 app.thread.scheduleTrimMemory(
14857 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014858 } catch (RemoteException e) {
14859 }
14860 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014861 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn27ff9132012-03-06 14:57:58 -080014862 } else {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014863 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackborn27ff9132012-03-06 14:57:58 -080014864 && app.pendingUiClean) {
14865 // If this application is now in the background and it
14866 // had done UI, then give it the special trim level to
14867 // have it free UI resources.
14868 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
14869 if (app.trimMemoryLevel < level && app.thread != null) {
14870 try {
14871 app.thread.scheduleTrimMemory(level);
14872 } catch (RemoteException e) {
14873 }
14874 }
14875 app.pendingUiClean = false;
14876 }
14877 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014878 try {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080014879 app.thread.scheduleTrimMemory(fgTrimLevel);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014880 } catch (RemoteException e) {
14881 }
14882 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -080014883 app.trimMemoryLevel = fgTrimLevel;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014884 }
14885 }
14886 } else {
14887 final int N = mLruProcesses.size();
14888 for (i=0; i<N; i++) {
14889 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070014890 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014891 && app.pendingUiClean) {
14892 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
14893 && app.thread != null) {
14894 try {
14895 app.thread.scheduleTrimMemory(
14896 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
14897 } catch (RemoteException e) {
14898 }
14899 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014900 app.pendingUiClean = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070014901 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -080014902 app.trimMemoryLevel = 0;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014903 }
14904 }
14905
14906 if (mAlwaysFinishActivities) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070014907 // Need to do this on its own message because the stack may not
14908 // be in a consistent state at this point.
14909 mMainStack.scheduleDestroyActivities(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014910 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014911 }
14912
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070014913 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014914 synchronized (this) {
14915 int i;
14916
14917 // First remove any unused application processes whose package
14918 // has been removed.
14919 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
14920 final ProcessRecord app = mRemovedProcesses.get(i);
14921 if (app.activities.size() == 0
14922 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080014923 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014924 TAG, "Exiting empty application process "
14925 + app.processName + " ("
14926 + (app.thread != null ? app.thread.asBinder() : null)
14927 + ")\n");
14928 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070014929 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
14930 app.processName, app.setAdj, "empty");
14931 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014932 } else {
14933 try {
14934 app.thread.scheduleExit();
14935 } catch (Exception e) {
14936 // Ignore exceptions.
14937 }
14938 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070014939 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014940 mRemovedProcesses.remove(i);
14941
14942 if (app.persistent) {
14943 if (app.persistent) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080014944 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014945 }
14946 }
14947 }
14948 }
14949
Dianne Hackbornce86ba82011-07-13 19:33:41 -070014950 // Now update the oom adj for all processes.
14951 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014952 }
14953 }
14954
14955 /** This method sends the specified signal to each of the persistent apps */
14956 public void signalPersistentProcesses(int sig) throws RemoteException {
14957 if (sig != Process.SIGNAL_USR1) {
14958 throw new SecurityException("Only SIGNAL_USR1 is allowed");
14959 }
14960
14961 synchronized (this) {
14962 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
14963 != PackageManager.PERMISSION_GRANTED) {
14964 throw new SecurityException("Requires permission "
14965 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
14966 }
14967
Dianne Hackborndd71fc82009-12-16 19:24:32 -080014968 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
14969 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014970 if (r.thread != null && r.persistent) {
14971 Process.sendSignal(r.pid, sig);
14972 }
14973 }
14974 }
14975 }
14976
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014977 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
14978 if (proc == null || proc == mProfileProc) {
14979 proc = mProfileProc;
14980 path = mProfileFile;
14981 profileType = mProfileType;
14982 clearProfilerLocked();
14983 }
14984 if (proc == null) {
14985 return;
14986 }
14987 try {
14988 proc.thread.profilerControl(false, path, null, profileType);
14989 } catch (RemoteException e) {
14990 throw new IllegalStateException("Process disappeared");
14991 }
14992 }
14993
14994 private void clearProfilerLocked() {
14995 if (mProfileFd != null) {
14996 try {
14997 mProfileFd.close();
14998 } catch (IOException e) {
14999 }
15000 }
15001 mProfileApp = null;
15002 mProfileProc = null;
15003 mProfileFile = null;
15004 mProfileType = 0;
15005 mAutoStopProfiler = false;
15006 }
15007
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015008 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070015009 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015010
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015011 try {
15012 synchronized (this) {
15013 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15014 // its own permission.
15015 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15016 != PackageManager.PERMISSION_GRANTED) {
15017 throw new SecurityException("Requires permission "
15018 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015019 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015020
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015021 if (start && fd == null) {
15022 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015023 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015024
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015025 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015026 if (process != null) {
15027 try {
15028 int pid = Integer.parseInt(process);
15029 synchronized (mPidsSelfLocked) {
15030 proc = mPidsSelfLocked.get(pid);
15031 }
15032 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015033 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015034
15035 if (proc == null) {
15036 HashMap<String, SparseArray<ProcessRecord>> all
15037 = mProcessNames.getMap();
15038 SparseArray<ProcessRecord> procs = all.get(process);
15039 if (procs != null && procs.size() > 0) {
15040 proc = procs.valueAt(0);
15041 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015042 }
15043 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015044
15045 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015046 throw new IllegalArgumentException("Unknown process: " + process);
15047 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015048
15049 if (start) {
15050 stopProfilerLocked(null, null, 0);
15051 setProfileApp(proc.info, proc.processName, path, fd, false);
15052 mProfileProc = proc;
15053 mProfileType = profileType;
15054 try {
15055 fd = fd.dup();
15056 } catch (IOException e) {
15057 fd = null;
15058 }
15059 proc.thread.profilerControl(start, path, fd, profileType);
15060 fd = null;
15061 mProfileFd = null;
15062 } else {
15063 stopProfilerLocked(proc, path, profileType);
15064 if (fd != null) {
15065 try {
15066 fd.close();
15067 } catch (IOException e) {
15068 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015069 }
15070 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070015071
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015072 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070015073 }
15074 } catch (RemoteException e) {
15075 throw new IllegalStateException("Process disappeared");
15076 } finally {
15077 if (fd != null) {
15078 try {
15079 fd.close();
15080 } catch (IOException e) {
15081 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080015082 }
15083 }
15084 }
Andy McFadden824c5102010-07-09 16:26:57 -070015085
15086 public boolean dumpHeap(String process, boolean managed,
15087 String path, ParcelFileDescriptor fd) throws RemoteException {
15088
15089 try {
15090 synchronized (this) {
15091 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
15092 // its own permission (same as profileControl).
15093 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
15094 != PackageManager.PERMISSION_GRANTED) {
15095 throw new SecurityException("Requires permission "
15096 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
15097 }
15098
15099 if (fd == null) {
15100 throw new IllegalArgumentException("null fd");
15101 }
15102
15103 ProcessRecord proc = null;
15104 try {
15105 int pid = Integer.parseInt(process);
15106 synchronized (mPidsSelfLocked) {
15107 proc = mPidsSelfLocked.get(pid);
15108 }
15109 } catch (NumberFormatException e) {
15110 }
15111
15112 if (proc == null) {
15113 HashMap<String, SparseArray<ProcessRecord>> all
15114 = mProcessNames.getMap();
15115 SparseArray<ProcessRecord> procs = all.get(process);
15116 if (procs != null && procs.size() > 0) {
15117 proc = procs.valueAt(0);
15118 }
15119 }
15120
15121 if (proc == null || proc.thread == null) {
15122 throw new IllegalArgumentException("Unknown process: " + process);
15123 }
15124
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080015125 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
15126 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070015127 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
15128 throw new SecurityException("Process not debuggable: " + proc);
15129 }
15130 }
15131
15132 proc.thread.dumpHeap(managed, path, fd);
15133 fd = null;
15134 return true;
15135 }
15136 } catch (RemoteException e) {
15137 throw new IllegalStateException("Process disappeared");
15138 } finally {
15139 if (fd != null) {
15140 try {
15141 fd.close();
15142 } catch (IOException e) {
15143 }
15144 }
15145 }
15146 }
15147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015148 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
15149 public void monitor() {
15150 synchronized (this) { }
15151 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015152
Dianne Hackborna573f6a2012-02-09 16:12:18 -080015153 void onCoreSettingsChange(Bundle settings) {
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080015154 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
15155 ProcessRecord processRecord = mLruProcesses.get(i);
15156 try {
15157 if (processRecord.thread != null) {
15158 processRecord.thread.setCoreSettings(settings);
15159 }
15160 } catch (RemoteException re) {
15161 /* ignore */
15162 }
15163 }
15164 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015165
15166 // Multi-user methods
15167
Amith Yamasani742a6712011-05-04 14:49:28 -070015168 private int mCurrentUserId;
15169 private SparseIntArray mLoggedInUsers = new SparseIntArray(5);
15170
15171 public boolean switchUser(int userId) {
15172 final int callingUid = Binder.getCallingUid();
15173 if (callingUid != 0 && callingUid != Process.myUid()) {
15174 Slog.e(TAG, "Trying to switch user from unauthorized app");
15175 return false;
15176 }
15177 if (mCurrentUserId == userId)
15178 return true;
15179
15180 synchronized (this) {
15181 // Check if user is already logged in, otherwise check if user exists first before
15182 // adding to the list of logged in users.
15183 if (mLoggedInUsers.indexOfKey(userId) < 0) {
15184 if (!userExists(userId)) {
15185 return false;
15186 }
15187 mLoggedInUsers.append(userId, userId);
15188 }
15189
15190 mCurrentUserId = userId;
15191 boolean haveActivities = mMainStack.switchUser(userId);
15192 if (!haveActivities) {
15193 startHomeActivityLocked(userId);
15194 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -080015195
Amith Yamasani37ce3a82012-02-06 12:04:42 -080015196 }
Amith Yamasani13593602012-03-22 16:16:17 -070015197
15198 // Inform of user switch
15199 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
15200 addedIntent.putExtra(Intent.EXTRA_USERID, userId);
15201 mContext.sendBroadcast(addedIntent, android.Manifest.permission.MANAGE_ACCOUNTS);
15202
Amith Yamasani4b2e9342011-03-31 12:38:53 -070015203 return true;
15204 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015205
Amith Yamasani52f1d752012-03-28 18:19:29 -070015206 @Override
15207 public UserInfo getCurrentUser() throws RemoteException {
15208 final int callingUid = Binder.getCallingUid();
15209 if (callingUid != 0 && callingUid != Process.myUid()) {
15210 Slog.e(TAG, "Trying to get user from unauthorized app");
15211 return null;
15212 }
15213 return AppGlobals.getPackageManager().getUser(mCurrentUserId);
15214 }
15215
Amith Yamasani13593602012-03-22 16:16:17 -070015216 private void onUserRemoved(Intent intent) {
15217 int extraUserId = intent.getIntExtra(Intent.EXTRA_USERID, -1);
15218 if (extraUserId < 1) return;
15219
15220 // Kill all the processes for the user
15221 ArrayList<Pair<String, Integer>> pkgAndUids = new ArrayList<Pair<String,Integer>>();
15222 synchronized (this) {
15223 HashMap<String,SparseArray<ProcessRecord>> map = mProcessNames.getMap();
15224 for (Entry<String, SparseArray<ProcessRecord>> uidMap : map.entrySet()) {
15225 SparseArray<ProcessRecord> uids = uidMap.getValue();
15226 for (int i = 0; i < uids.size(); i++) {
15227 if (UserId.getUserId(uids.keyAt(i)) == extraUserId) {
15228 pkgAndUids.add(new Pair<String,Integer>(uidMap.getKey(), uids.keyAt(i)));
15229 }
15230 }
15231 }
15232
15233 for (Pair<String,Integer> pkgAndUid : pkgAndUids) {
15234 forceStopPackageLocked(pkgAndUid.first, pkgAndUid.second,
15235 false, false, true, true, extraUserId);
15236 }
15237 }
15238 }
15239
Amith Yamasani742a6712011-05-04 14:49:28 -070015240 private boolean userExists(int userId) {
15241 try {
Amith Yamasani13593602012-03-22 16:16:17 -070015242 UserInfo user = AppGlobals.getPackageManager().getUser(userId);
15243 return user != null;
Amith Yamasani742a6712011-05-04 14:49:28 -070015244 } catch (RemoteException re) {
15245 // Won't happen, in same process
15246 }
15247
15248 return false;
15249 }
15250
Amith Yamasani37ce3a82012-02-06 12:04:42 -080015251 private void checkValidCaller(int uid, int userId) {
15252 if (UserId.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
15253
15254 throw new SecurityException("Caller uid=" + uid
15255 + " is not privileged to communicate with user=" + userId);
15256 }
Amith Yamasani742a6712011-05-04 14:49:28 -070015257
15258 private int applyUserId(int uid, int userId) {
15259 return UserId.getUid(userId, uid);
15260 }
15261
15262 private ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080015263 if (info == null) return null;
Amith Yamasani742a6712011-05-04 14:49:28 -070015264 ApplicationInfo newInfo = new ApplicationInfo(info);
15265 newInfo.uid = applyUserId(info.uid, userId);
Amith Yamasania4a54e22012-04-16 15:44:19 -070015266 newInfo.dataDir = USER_DATA_DIR + userId + "/"
15267 + info.packageName;
Amith Yamasani742a6712011-05-04 14:49:28 -070015268 return newInfo;
15269 }
15270
15271 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
Amith Yamasania4a54e22012-04-16 15:44:19 -070015272 if (aInfo == null
15273 || (userId < 1 && aInfo.applicationInfo.uid < UserId.PER_USER_RANGE)) {
Amith Yamasani742a6712011-05-04 14:49:28 -070015274 return aInfo;
15275 }
15276
15277 ActivityInfo info = new ActivityInfo(aInfo);
15278 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
15279 return info;
15280 }
15281
15282 static class ServiceMap {
15283
15284 private final SparseArray<HashMap<ComponentName, ServiceRecord>> mServicesByNamePerUser
15285 = new SparseArray<HashMap<ComponentName, ServiceRecord>>();
15286 private final SparseArray<HashMap<Intent.FilterComparison, ServiceRecord>>
15287 mServicesByIntentPerUser = new SparseArray<
15288 HashMap<Intent.FilterComparison, ServiceRecord>>();
15289
15290 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
15291 // TODO: Deal with global services
15292 if (DEBUG_MU)
15293 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
15294 return getServices(callingUser).get(name);
15295 }
15296
15297 ServiceRecord getServiceByName(ComponentName name) {
15298 return getServiceByName(name, -1);
15299 }
15300
15301 ServiceRecord getServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15302 // TODO: Deal with global services
15303 if (DEBUG_MU)
15304 Slog.v(TAG_MU, "getServiceByIntent(" + filter + "), callingUser = " + callingUser);
15305 return getServicesByIntent(callingUser).get(filter);
15306 }
15307
15308 ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
15309 return getServiceByIntent(filter, -1);
15310 }
15311
15312 void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
15313 // TODO: Deal with global services
15314 getServices(callingUser).put(name, value);
15315 }
15316
15317 void putServiceByIntent(Intent.FilterComparison filter, int callingUser,
15318 ServiceRecord value) {
15319 // TODO: Deal with global services
15320 getServicesByIntent(callingUser).put(filter, value);
15321 }
15322
15323 void removeServiceByName(ComponentName name, int callingUser) {
15324 // TODO: Deal with global services
15325 ServiceRecord removed = getServices(callingUser).remove(name);
15326 if (DEBUG_MU)
15327 Slog.v(TAG, "removeServiceByName user=" + callingUser + " name=" + name
15328 + " removed=" + removed);
15329 }
15330
15331 void removeServiceByIntent(Intent.FilterComparison filter, int callingUser) {
15332 // TODO: Deal with global services
15333 ServiceRecord removed = getServicesByIntent(callingUser).remove(filter);
15334 if (DEBUG_MU)
15335 Slog.v(TAG_MU, "removeServiceByIntent user=" + callingUser + " intent=" + filter
15336 + " removed=" + removed);
15337 }
15338
15339 Collection<ServiceRecord> getAllServices(int callingUser) {
15340 // TODO: Deal with global services
15341 return getServices(callingUser).values();
15342 }
15343
15344 private HashMap<ComponentName, ServiceRecord> getServices(int callingUser) {
15345 HashMap map = mServicesByNamePerUser.get(callingUser);
15346 if (map == null) {
15347 map = new HashMap<ComponentName, ServiceRecord>();
15348 mServicesByNamePerUser.put(callingUser, map);
15349 }
15350 return map;
15351 }
15352
15353 private HashMap<Intent.FilterComparison, ServiceRecord> getServicesByIntent(
15354 int callingUser) {
15355 HashMap map = mServicesByIntentPerUser.get(callingUser);
15356 if (map == null) {
15357 map = new HashMap<Intent.FilterComparison, ServiceRecord>();
15358 mServicesByIntentPerUser.put(callingUser, map);
15359 }
15360 return map;
15361 }
15362 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015363}