blob: 62af91e7602316267d26c0abd0c2981cb643e530 [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 Hackborn1676c852012-09-10 14:52:30 -070030import com.android.server.pm.UserManagerService;
Craig Mautner4b71aa12012-12-27 17:20:01 -080031import com.android.server.wm.AppTransition;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080032import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
Dianne Hackborndd71fc82009-12-16 19:24:32 -080034import dalvik.system.Zygote;
35
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.app.Activity;
37import android.app.ActivityManager;
38import android.app.ActivityManagerNative;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070039import android.app.ActivityOptions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.app.ActivityThread;
41import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070042import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020043import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070045import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.app.IApplicationThread;
47import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070048import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070049import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.app.IServiceConnection;
Dianne Hackborn80a4af22012-08-27 19:18:31 -070051import android.app.IStopUserCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.app.IThumbnailReceiver;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070053import android.app.IUserSwitchObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070055import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070056import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.app.PendingIntent;
Christopher Tate45281862010-03-05 15:46:30 -080058import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020059import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080060import android.content.BroadcastReceiver;
Dianne Hackborn21c241e2012-03-08 13:57:23 -080061import android.content.ClipData;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070062import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.content.ComponentName;
Jeff Sharkey110a6b62012-03-12 11:12:41 -070064import android.content.ContentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.content.ContentResolver;
66import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020067import android.content.DialogInterface;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070068import android.content.IContentProvider;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070069import android.content.IIntentReceiver;
70import android.content.IIntentSender;
Adam Powelldd8fab22012-03-22 17:47:27 -070071import android.content.Intent;
72import android.content.IntentFilter;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070073import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.content.pm.ActivityInfo;
75import android.content.pm.ApplicationInfo;
76import android.content.pm.ConfigurationInfo;
77import android.content.pm.IPackageDataObserver;
78import android.content.pm.IPackageManager;
79import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080080import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.content.pm.PackageManager;
Amith Yamasani258848d2012-08-10 17:06:33 -070082import android.content.pm.UserInfo;
Adam Powelldd8fab22012-03-22 17:47:27 -070083import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070084import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.content.pm.ProviderInfo;
86import android.content.pm.ResolveInfo;
87import android.content.pm.ServiceInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040088import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import android.content.res.Configuration;
90import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070091import android.net.Proxy;
92import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import android.net.Uri;
94import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080095import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080096import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070097import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080098import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -0800100import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101import android.os.FileUtils;
102import android.os.Handler;
103import android.os.IBinder;
104import android.os.IPermissionController;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700105import android.os.IRemoteCallback;
Dianne Hackborn1676c852012-09-10 14:52:30 -0700106import android.os.IUserManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107import android.os.Looper;
108import android.os.Message;
109import android.os.Parcel;
110import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700112import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113import android.os.RemoteException;
rpcraigec7ed14c2012-07-25 13:10:37 -0400114import android.os.SELinux;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700116import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117import android.os.SystemClock;
118import android.os.SystemProperties;
Christopher Tate73c2aee2012-03-15 16:27:14 -0700119import android.os.UpdateLock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700120import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121import android.provider.Settings;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700122import android.text.format.Time;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import android.util.EventLog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800124import android.util.Log;
Adam Powelldd8fab22012-03-22 17:47:27 -0700125import android.util.Pair;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import android.util.PrintWriterPrinter;
Adam Powelldd8fab22012-03-22 17:47:27 -0700127import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128import android.util.SparseArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700129import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130import android.view.Gravity;
131import android.view.LayoutInflater;
132import android.view.View;
133import android.view.WindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700135import java.io.BufferedInputStream;
136import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700137import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700138import java.io.DataInputStream;
139import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140import java.io.File;
141import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700142import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700144import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200145import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800146import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700148import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800149import java.lang.ref.WeakReference;
150import java.util.ArrayList;
Dianne Hackbornc72fc672012-09-20 13:12:03 -0700151import java.util.Arrays;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700152import java.util.Collections;
153import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800154import java.util.HashMap;
155import java.util.HashSet;
156import java.util.Iterator;
157import java.util.List;
158import java.util.Locale;
159import java.util.Map;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700160import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700161import java.util.concurrent.atomic.AtomicBoolean;
162import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800163
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700164public final class ActivityManagerService extends ActivityManagerNative
165 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
Amith Yamasani742a6712011-05-04 14:49:28 -0700166 private static final String USER_DATA_DIR = "/data/user/";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167 static final String TAG = "ActivityManager";
Amith Yamasani742a6712011-05-04 14:49:28 -0700168 static final String TAG_MU = "ActivityManagerServiceMU";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400170 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800171 static final boolean DEBUG_SWITCH = localLOGV || false;
172 static final boolean DEBUG_TASKS = localLOGV || false;
Dianne Hackborn15491c62012-09-19 10:59:14 -0700173 static final boolean DEBUG_THUMBNAILS = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174 static final boolean DEBUG_PAUSE = localLOGV || false;
175 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
176 static final boolean DEBUG_TRANSITION = localLOGV || false;
177 static final boolean DEBUG_BROADCAST = localLOGV || false;
Christopher Tatef46723b2012-01-26 14:19:24 -0800178 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700179 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800180 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700181 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182 static final boolean DEBUG_VISBILITY = localLOGV || false;
183 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700184 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
Dianne Hackborncc5a0552012-10-01 16:32:39 -0700185 static final boolean DEBUG_CLEANUP = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700186 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800187 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800188 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700189 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700190 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700191 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700192 static final boolean DEBUG_POWER = localLOGV || false;
193 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
Amith Yamasani742a6712011-05-04 14:49:28 -0700194 static final boolean DEBUG_MU = localLOGV || false;
Christopher Tate73c2aee2012-03-15 16:27:14 -0700195 static final boolean DEBUG_IMMERSIVE = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196 static final boolean VALIDATE_TOKENS = false;
197 static final boolean SHOW_ACTIVITY_START_TIME = true;
198
199 // Control over CPU and battery monitoring.
200 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
201 static final boolean MONITOR_CPU_USAGE = true;
202 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
203 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
204 static final boolean MONITOR_THREAD_CPU_USAGE = false;
205
Dianne Hackborn1655be42009-05-08 14:29:01 -0700206 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700207 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700208
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800209 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800210
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700211 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213 // Maximum number of recent tasks that we can remember.
214 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700215
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700216 // Amount of time after a call to stopAppSwitches() during which we will
217 // prevent further untrusted switches from happening.
218 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219
220 // How long we wait for a launched process to attach to the activity manager
221 // before we decide it's never going to come up for real.
222 static final int PROC_START_TIMEOUT = 10*1000;
223
Jeff Brown3f9dd282011-07-08 20:02:19 -0700224 // How long we wait for a launched process to attach to the activity manager
225 // before we decide it's never going to come up for real, when the process was
226 // started with a wrapper for instrumentation (such as Valgrind) because it
227 // could take much longer than usual.
228 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 // How long to wait after going idle before forcing apps to GC.
231 static final int GC_TIMEOUT = 5*1000;
232
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700233 // The minimum amount of time between successive GC requests for a process.
234 static final int GC_MIN_INTERVAL = 60*1000;
235
Dianne Hackborn287952c2010-09-22 22:34:31 -0700236 // The rate at which we check for apps using excessive power -- 15 mins.
237 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
238
239 // The minimum sample duration we will allow before deciding we have
240 // enough data on wake locks to start killing things.
241 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
242
243 // The minimum sample duration we will allow before deciding we have
244 // enough data on CPU usage to start killing things.
245 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700246
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 // How long we allow a receiver to run before giving up on it.
Christopher Tatef46723b2012-01-26 14:19:24 -0800248 static final int BROADCAST_FG_TIMEOUT = 10*1000;
249 static final int BROADCAST_BG_TIMEOUT = 60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800250
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251 // How long we wait until we timeout on key dispatching.
252 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 // How long we wait until we timeout on key dispatching during instrumentation.
255 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
256
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700257 // Amount of time we wait for observers to handle a user switch before
258 // giving up on them and unfreezing the screen.
259 static final int USER_SWITCH_TIMEOUT = 2*1000;
260
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -0700261 // Maximum number of users we allow to be running at a time.
262 static final int MAX_RUNNING_USERS = 3;
263
Dan Egnor42471dd2010-01-07 17:25:22 -0800264 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265
266 static final String[] EMPTY_STRING_ARRAY = new String[0];
267
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700268 public ActivityStack mMainStack;
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700269
270 private final boolean mHeadless;
271
Joe Onorato54a4a412011-11-02 20:50:08 -0700272 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
273 // default actuion automatically. Important for devices without direct input
274 // devices.
275 private boolean mShowDialogs = true;
276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700278 * Description of a request to start a new activity, which has been held
279 * due to app switches being disabled.
280 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700281 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700282 ActivityRecord r;
283 ActivityRecord sourceRecord;
Dianne Hackborna4972e92012-03-14 10:38:05 -0700284 int startFlags;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700285 }
286
287 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
288 = new ArrayList<PendingActivityLaunch>();
289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800290
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800291 BroadcastQueue mFgBroadcastQueue;
292 BroadcastQueue mBgBroadcastQueue;
Christopher Tatef46723b2012-01-26 14:19:24 -0800293 // Convenient for easy iteration over the queues. Foreground is first
294 // so that dispatch of foreground broadcasts gets precedence.
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800295 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
Christopher Tatef46723b2012-01-26 14:19:24 -0800296
297 BroadcastQueue broadcastQueueForIntent(Intent intent) {
298 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
299 if (DEBUG_BACKGROUND_BROADCAST) {
300 Slog.i(TAG, "Broadcast intent " + intent + " on "
301 + (isFg ? "foreground" : "background")
302 + " queue");
303 }
304 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
305 }
306
307 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
308 for (BroadcastQueue queue : mBroadcastQueues) {
309 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
310 if (r != null) {
311 return r;
312 }
313 }
314 return null;
315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316
317 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 * Activity we have told the window manager to have key focus.
319 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700320 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700321 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 * List of intents that were used to start the most recent tasks.
323 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700324 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325
326 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700327 * Process management.
328 */
329 final ProcessList mProcessList = new ProcessList();
330
331 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 * All of the applications we currently have running organized by name.
333 * The keys are strings of the application package name (as
334 * returned by the package manager), and the keys are ApplicationRecord
335 * objects.
336 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700337 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338
339 /**
Dianne Hackborna0c283e2012-02-09 10:47:01 -0800340 * The currently running isolated processes.
341 */
342 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
343
344 /**
345 * Counter for assigning isolated process uids, to avoid frequently reusing the
346 * same ones.
347 */
348 int mNextIsolatedProcessUid = 0;
349
350 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700351 * The currently running heavy-weight process, if any.
352 */
353 ProcessRecord mHeavyWeightProcess = null;
354
355 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 * The last time that various processes have crashed.
357 */
358 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
359
360 /**
361 * Set of applications that we consider to be bad, and will reject
362 * incoming broadcasts from (which the user has no control over).
363 * Processes are added to this set when they have crashed twice within
364 * a minimum amount of time; they are removed from it when they are
365 * later restarted (hopefully due to some user action). The value is the
366 * time it was added to the list.
367 */
368 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
369
370 /**
371 * All of the processes we currently have running organized by pid.
372 * The keys are the pid running the application.
373 *
374 * <p>NOTE: This object is protected by its own lock, NOT the global
375 * activity manager lock!
376 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700377 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378
379 /**
380 * All of the processes that have been forced to be foreground. The key
381 * is the pid of the caller who requested it (we hold a death
382 * link on it).
383 */
384 abstract class ForegroundToken implements IBinder.DeathRecipient {
385 int pid;
386 IBinder token;
387 }
388 final SparseArray<ForegroundToken> mForegroundProcesses
389 = new SparseArray<ForegroundToken>();
390
391 /**
392 * List of records for processes that someone had tried to start before the
393 * system was ready. We don't start them at that point, but ensure they
394 * are started by the time booting is complete.
395 */
396 final ArrayList<ProcessRecord> mProcessesOnHold
397 = new ArrayList<ProcessRecord>();
398
399 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 * List of persistent applications that are in the process
401 * of being started.
402 */
403 final ArrayList<ProcessRecord> mPersistentStartingProcesses
404 = new ArrayList<ProcessRecord>();
405
406 /**
407 * Processes that are being forcibly torn down.
408 */
409 final ArrayList<ProcessRecord> mRemovedProcesses
410 = new ArrayList<ProcessRecord>();
411
412 /**
413 * List of running applications, sorted by recent usage.
414 * The first entry in the list is the least recently used.
415 * It contains ApplicationRecord objects. This list does NOT include
416 * any persistent application records (since we never want to exit them).
417 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800418 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800419 = new ArrayList<ProcessRecord>();
420
421 /**
422 * List of processes that should gc as soon as things are idle.
423 */
424 final ArrayList<ProcessRecord> mProcessesToGc
425 = new ArrayList<ProcessRecord>();
426
427 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800428 * This is the process holding what we currently consider to be
429 * the "home" activity.
430 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700431 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800432
433 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700434 * This is the process holding the activity the user last visited that
435 * is in a different process from the one they are currently in.
436 */
437 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -0800438
439 /**
440 * The time at which the previous process was last visible.
441 */
442 long mPreviousProcessVisibleTime;
443
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700444 /**
Dianne Hackborn80a4af22012-08-27 19:18:31 -0700445 * Which uses have been started, so are allowed to run code.
446 */
447 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
448
449 /**
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -0700450 * LRU list of history of current users. Most recently current is at the end.
451 */
452 final ArrayList<Integer> mUserLru = new ArrayList<Integer>();
453
454 /**
Dianne Hackbornc72fc672012-09-20 13:12:03 -0700455 * Constant array of the users that are currently started.
456 */
457 int[] mStartedUserArray = new int[] { 0 };
458
459 /**
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700460 * Registered observers of the user switching mechanics.
461 */
462 final RemoteCallbackList<IUserSwitchObserver> mUserSwitchObservers
463 = new RemoteCallbackList<IUserSwitchObserver>();
464
465 /**
466 * Currently active user switch.
467 */
468 Object mCurUserSwitchCallback;
469
470 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400471 * Packages that the user has asked to have run in screen size
472 * compatibility mode instead of filling the screen.
473 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700474 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400475
476 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 * Set of PendingResultRecord objects that are currently active.
478 */
479 final HashSet mPendingResultRecords = new HashSet();
480
481 /**
482 * Set of IntentSenderRecord objects that are currently active.
483 */
484 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
485 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
486
487 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800488 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700489 * already logged DropBox entries for. Guarded by itself. If
490 * something (rogue user app) forces this over
491 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
492 */
493 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
494 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
495
496 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700497 * Strict Mode background batched logging state.
498 *
499 * The string buffer is guarded by itself, and its lock is also
500 * used to determine if another batched write is already
501 * in-flight.
502 */
503 private final StringBuilder mStrictModeBuffer = new StringBuilder();
504
505 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 * Keeps track of all IIntentReceivers that have been registered for
507 * broadcasts. Hash keys are the receiver IBinder, hash value is
508 * a ReceiverList.
509 */
510 final HashMap mRegisteredReceivers = new HashMap();
511
512 /**
513 * Resolver for broadcast intents to registered receivers.
514 * Holds BroadcastFilter (subclass of IntentFilter).
515 */
516 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
517 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
518 @Override
519 protected boolean allowFilterResult(
520 BroadcastFilter filter, List<BroadcastFilter> dest) {
521 IBinder target = filter.receiverList.receiver.asBinder();
522 for (int i=dest.size()-1; i>=0; i--) {
523 if (dest.get(i).receiverList.receiver.asBinder() == target) {
524 return false;
525 }
526 }
527 return true;
528 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700529
530 @Override
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700531 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
Dianne Hackborn20e80982012-08-31 19:00:44 -0700532 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
533 || userId == filter.owningUserId) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700534 return super.newResult(filter, match, userId);
535 }
536 return null;
537 }
538
539 @Override
Dianne Hackborn9ec6cdd2012-05-31 10:57:54 -0700540 protected BroadcastFilter[] newArray(int size) {
541 return new BroadcastFilter[size];
542 }
543
544 @Override
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700545 protected String packageForFilter(BroadcastFilter filter) {
546 return filter.packageName;
547 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 };
549
550 /**
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700551 * State of all active sticky broadcasts per user. Keys are the action of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 * sticky Intent, values are an ArrayList of all broadcasted intents with
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700553 * that action (which should usually be one). The SparseArray is keyed
554 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
555 * for stickies that are sent to all users.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 */
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700557 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
558 new SparseArray<HashMap<String, ArrayList<Intent>>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800559
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700560 final ActiveServices mServices;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561
562 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700563 * Backup/restore process management
564 */
565 String mBackupAppName = null;
566 BackupRecord mBackupTarget = null;
567
568 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800569 * List of PendingThumbnailsRecord objects of clients who are still
570 * waiting to receive all of the thumbnails for a task.
571 */
572 final ArrayList mPendingThumbnails = new ArrayList();
573
574 /**
575 * List of HistoryRecord objects that have been finished and must
576 * still report back to a pending thumbnail receiver.
577 */
578 final ArrayList mCancelledThumbnails = new ArrayList();
579
Dianne Hackborn2d1b3782012-09-09 17:49:39 -0700580 final ProviderMap mProviderMap;
Amith Yamasani742a6712011-05-04 14:49:28 -0700581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 /**
583 * List of content providers who have clients waiting for them. The
584 * application is currently being launched and the provider will be
585 * removed from this list once it is published.
586 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700587 final ArrayList<ContentProviderRecord> mLaunchingProviders
588 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800589
590 /**
591 * Global set of specific Uri permissions that have been granted.
592 */
593 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
594 = new SparseArray<HashMap<Uri, UriPermission>>();
595
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800596 CoreSettingsObserver mCoreSettingsObserver;
597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 /**
599 * Thread-local storage used to carry caller permissions over through
600 * indirect content-provider access.
601 * @see #ActivityManagerService.openContentUri()
602 */
603 private class Identity {
604 public int pid;
605 public int uid;
606
607 Identity(int _pid, int _uid) {
608 pid = _pid;
609 uid = _uid;
610 }
611 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700612
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
614
615 /**
616 * All information we have collected about the runtime performance of
617 * any user id that can impact battery performance.
618 */
619 final BatteryStatsService mBatteryStatsService;
620
621 /**
622 * information about component usage
623 */
624 final UsageStatsService mUsageStatsService;
625
626 /**
627 * Current configuration information. HistoryRecord objects are given
628 * a reference to this object to indicate which configuration they are
629 * currently running in, so this object must be kept immutable.
630 */
631 Configuration mConfiguration = new Configuration();
632
633 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800634 * Current sequencing integer of the configuration, for skipping old
635 * configurations.
636 */
637 int mConfigurationSeq = 0;
638
639 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700640 * Hardware-reported OpenGLES version.
641 */
642 final int GL_ES_VERSION;
643
644 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800645 * List of initialization arguments to pass to all processes when binding applications to them.
646 * For example, references to the commonly used services.
647 */
648 HashMap<String, IBinder> mAppBindArgs;
649
650 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700651 * Temporary to avoid allocations. Protected by main lock.
652 */
653 final StringBuilder mStringBuilder = new StringBuilder(256);
654
655 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800656 * Used to control how we initialize the service.
657 */
658 boolean mStartRunning = false;
659 ComponentName mTopComponent;
660 String mTopAction;
661 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700662 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800663 boolean mSystemReady = false;
664 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700665 boolean mWaitingUpdate = false;
666 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700667 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700668 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800669
670 Context mContext;
671
672 int mFactoryTest;
673
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700674 boolean mCheckedForSetup;
675
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700677 * The time at which we will allow normal application switches again,
678 * after a call to {@link #stopAppSwitches()}.
679 */
680 long mAppSwitchesAllowedTime;
681
682 /**
683 * This is set to true after the first switch after mAppSwitchesAllowedTime
684 * is set; any switches after that will clear the time.
685 */
686 boolean mDidAppSwitch;
687
688 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700689 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700690 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700691 long mLastPowerCheckRealtime;
692
693 /**
694 * Last time (in uptime) at which we checked for power usage.
695 */
696 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700697
698 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 * Set while we are wanting to sleep, to prevent any
700 * activities from being started/resumed.
701 */
702 boolean mSleeping = false;
703
704 /**
Dianne Hackbornff5b1582012-04-12 17:24:07 -0700705 * State of external calls telling us if the device is asleep.
706 */
707 boolean mWentToSleep = false;
708
709 /**
710 * State of external call telling us if the lock screen is shown.
711 */
712 boolean mLockScreenShown = false;
713
714 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700715 * Set if we are shutting down the system, similar to sleeping.
716 */
717 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800718
719 /**
720 * Task identifier that activities are currently being started
721 * in. Incremented each time a new task is created.
722 * todo: Replace this with a TokenSpace class that generates non-repeating
723 * integers that won't wrap.
724 */
725 int mCurTask = 1;
726
727 /**
728 * Current sequence id for oom_adj computation traversal.
729 */
730 int mAdjSeq = 0;
731
732 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700733 * Current sequence id for process LRU updating.
734 */
735 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800736
737 /**
Dianne Hackbornee7621c2012-08-13 16:42:18 -0700738 * Keep track of the non-hidden/empty process we last found, to help
739 * determine how to distribute hidden/empty processes next time.
740 */
741 int mNumNonHiddenProcs = 0;
742
743 /**
744 * Keep track of the number of hidden procs, to balance oom adj
745 * distribution between those and empty procs.
746 */
747 int mNumHiddenProcs = 0;
748
749 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700750 * Keep track of the number of service processes we last found, to
751 * determine on the next iteration which should be B services.
752 */
753 int mNumServiceProcs = 0;
754 int mNewNumServiceProcs = 0;
755
756 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 * System monitoring: number of processes that died since the last
758 * N procs were started.
759 */
760 int[] mProcDeaths = new int[20];
761
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700762 /**
763 * This is set if we had to do a delayed dexopt of an app before launching
764 * it, to increasing the ANR timeouts in that case.
765 */
766 boolean mDidDexOpt;
767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 String mDebugApp = null;
769 boolean mWaitForDebugger = false;
770 boolean mDebugTransient = false;
771 String mOrigDebugApp = null;
772 boolean mOrigWaitForDebugger = false;
773 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700774 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700775 String mProfileApp = null;
776 ProcessRecord mProfileProc = null;
777 String mProfileFile;
778 ParcelFileDescriptor mProfileFd;
779 int mProfileType = 0;
780 boolean mAutoStopProfiler = false;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800781 String mOpenGlTraceApp = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700783 static class ProcessChangeItem {
784 static final int CHANGE_ACTIVITIES = 1<<0;
785 static final int CHANGE_IMPORTANCE= 1<<1;
786 int changes;
787 int uid;
788 int pid;
789 int importance;
790 boolean foregroundActivities;
791 }
792
Jeff Sharkeya4620792011-05-20 15:29:23 -0700793 final RemoteCallbackList<IProcessObserver> mProcessObservers
794 = new RemoteCallbackList<IProcessObserver>();
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700795 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
796
797 final ArrayList<ProcessChangeItem> mPendingProcessChanges
798 = new ArrayList<ProcessChangeItem>();
799 final ArrayList<ProcessChangeItem> mAvailProcessChanges
800 = new ArrayList<ProcessChangeItem>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 /**
803 * Callback of last caller to {@link #requestPss}.
804 */
805 Runnable mRequestPssCallback;
806
807 /**
808 * Remaining processes for which we are waiting results from the last
809 * call to {@link #requestPss}.
810 */
811 final ArrayList<ProcessRecord> mRequestPssList
812 = new ArrayList<ProcessRecord>();
813
814 /**
815 * Runtime statistics collection thread. This object's lock is used to
816 * protect all related state.
817 */
818 final Thread mProcessStatsThread;
819
820 /**
821 * Used to collect process stats when showing not responding dialog.
822 * Protected by mProcessStatsThread.
823 */
824 final ProcessStats mProcessStats = new ProcessStats(
825 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700826 final AtomicLong mLastCpuTime = new AtomicLong(0);
827 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
828
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800829 long mLastWriteTime = 0;
830
831 /**
Christopher Tate73c2aee2012-03-15 16:27:14 -0700832 * Used to retain an update lock when the foreground activity is in
833 * immersive mode.
834 */
835 final UpdateLock mUpdateLock = new UpdateLock("immersive");
836
837 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 * Set to true after the system has finished booting.
839 */
840 boolean mBooted = false;
841
Dianne Hackborn7d608422011-08-07 16:24:18 -0700842 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700843 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844
845 WindowManagerService mWindowManager;
846
847 static ActivityManagerService mSelf;
848 static ActivityThread mSystemThread;
849
Dianne Hackbornc72fc672012-09-20 13:12:03 -0700850 private int mCurrentUserId = 0;
851 private int[] mCurrentUserArray = new int[] { 0 };
Dianne Hackborn1676c852012-09-10 14:52:30 -0700852 private UserManagerService mUserManager;
Amith Yamasani258848d2012-08-10 17:06:33 -0700853
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800854 private final class AppDeathRecipient implements IBinder.DeathRecipient {
855 final ProcessRecord mApp;
856 final int mPid;
857 final IApplicationThread mAppThread;
858
859 AppDeathRecipient(ProcessRecord app, int pid,
860 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800861 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862 TAG, "New death recipient " + this
863 + " for thread " + thread.asBinder());
864 mApp = app;
865 mPid = pid;
866 mAppThread = thread;
867 }
868
869 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800870 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800871 TAG, "Death received in " + this
872 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800873 synchronized(ActivityManagerService.this) {
874 appDiedLocked(mApp, mPid, mAppThread);
875 }
876 }
877 }
878
879 static final int SHOW_ERROR_MSG = 1;
880 static final int SHOW_NOT_RESPONDING_MSG = 2;
881 static final int SHOW_FACTORY_ERROR_MSG = 3;
882 static final int UPDATE_CONFIGURATION_MSG = 4;
883 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
884 static final int WAIT_FOR_DEBUGGER_MSG = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 static final int SERVICE_TIMEOUT_MSG = 12;
886 static final int UPDATE_TIME_ZONE = 13;
887 static final int SHOW_UID_ERROR_MSG = 14;
888 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700890 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700891 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800892 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700893 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
894 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700895 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700896 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700897 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700898 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700899 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700900 static final int DISPATCH_PROCESSES_CHANGED = 31;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700901 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700902 static final int REPORT_MEM_USAGE = 33;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700903 static final int REPORT_USER_SWITCH_MSG = 34;
904 static final int CONTINUE_USER_SWITCH_MSG = 35;
905 static final int USER_SWITCH_TIMEOUT_MSG = 36;
Christopher Tate73c2aee2012-03-15 16:27:14 -0700906 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800908 static final int FIRST_ACTIVITY_STACK_MSG = 100;
909 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
910 static final int FIRST_COMPAT_MODE_MSG = 300;
911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700913 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700914 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800915
916 final Handler mHandler = new Handler() {
917 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800918 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 //}
920
921 public void handleMessage(Message msg) {
922 switch (msg.what) {
923 case SHOW_ERROR_MSG: {
924 HashMap data = (HashMap) msg.obj;
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700925 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
926 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 synchronized (ActivityManagerService.this) {
928 ProcessRecord proc = (ProcessRecord)data.get("app");
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700929 AppErrorResult res = (AppErrorResult) data.get("result");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800931 Slog.e(TAG, "App already has crash dialog: " + proc);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700932 if (res != null) {
933 res.set(0);
934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 return;
936 }
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700937 if (!showBackground && UserHandle.getAppId(proc.uid)
938 >= Process.FIRST_APPLICATION_UID && proc.userId != mCurrentUserId
939 && proc.pid != MY_PID) {
940 Slog.w(TAG, "Skipping crash dialog of " + proc + ": background");
941 if (res != null) {
942 res.set(0);
943 }
944 return;
945 }
Joe Onorato54a4a412011-11-02 20:50:08 -0700946 if (mShowDialogs && !mSleeping && !mShuttingDown) {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700947 Dialog d = new AppErrorDialog(mContext,
948 ActivityManagerService.this, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800949 d.show();
950 proc.crashDialog = d;
951 } else {
952 // The device is asleep, so just pretend that the user
953 // saw a crash dialog and hit "force quit".
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -0700954 if (res != null) {
955 res.set(0);
956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 }
958 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700959
960 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 } break;
962 case SHOW_NOT_RESPONDING_MSG: {
963 synchronized (ActivityManagerService.this) {
964 HashMap data = (HashMap) msg.obj;
965 ProcessRecord proc = (ProcessRecord)data.get("app");
966 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800967 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 return;
969 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800970
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700971 Intent intent = new Intent("android.intent.action.ANR");
972 if (!mProcessesReady) {
Christopher Tatef46723b2012-01-26 14:19:24 -0800973 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
974 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700975 }
976 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800977 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700978 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800979
Justin Kohbc52ca22012-03-29 15:11:44 -0700980 if (mShowDialogs) {
981 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -0700982 mContext, proc, (ActivityRecord)data.get("activity"),
983 msg.arg1 != 0);
Justin Kohbc52ca22012-03-29 15:11:44 -0700984 d.show();
985 proc.anrDialog = d;
986 } else {
987 // Just kill the app if there is no dialog to be shown.
988 killAppAtUsersRequest(proc, null);
989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700991
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700992 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700994 case SHOW_STRICT_MODE_VIOLATION_MSG: {
995 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
996 synchronized (ActivityManagerService.this) {
997 ProcessRecord proc = (ProcessRecord) data.get("app");
998 if (proc == null) {
999 Slog.e(TAG, "App not found when showing strict mode dialog.");
1000 break;
1001 }
1002 if (proc.crashDialog != null) {
1003 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1004 return;
1005 }
1006 AppErrorResult res = (AppErrorResult) data.get("result");
Joe Onorato54a4a412011-11-02 20:50:08 -07001007 if (mShowDialogs && !mSleeping && !mShuttingDown) {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07001008 Dialog d = new StrictModeViolationDialog(mContext,
1009 ActivityManagerService.this, res, proc);
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07001010 d.show();
1011 proc.crashDialog = d;
1012 } else {
1013 // The device is asleep, so just pretend that the user
1014 // saw a crash dialog and hit "force quit".
1015 res.set(0);
1016 }
1017 }
1018 ensureBootCompleted();
1019 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 case SHOW_FACTORY_ERROR_MSG: {
1021 Dialog d = new FactoryErrorDialog(
1022 mContext, msg.getData().getCharSequence("msg"));
1023 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001024 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001025 } break;
1026 case UPDATE_CONFIGURATION_MSG: {
1027 final ContentResolver resolver = mContext.getContentResolver();
1028 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
1029 } break;
1030 case GC_BACKGROUND_PROCESSES_MSG: {
1031 synchronized (ActivityManagerService.this) {
1032 performAppGcsIfAppropriateLocked();
1033 }
1034 } break;
1035 case WAIT_FOR_DEBUGGER_MSG: {
1036 synchronized (ActivityManagerService.this) {
1037 ProcessRecord app = (ProcessRecord)msg.obj;
1038 if (msg.arg1 != 0) {
1039 if (!app.waitedForDebugger) {
1040 Dialog d = new AppWaitingForDebuggerDialog(
1041 ActivityManagerService.this,
1042 mContext, app);
1043 app.waitDialog = d;
1044 app.waitedForDebugger = true;
1045 d.show();
1046 }
1047 } else {
1048 if (app.waitDialog != null) {
1049 app.waitDialog.dismiss();
1050 app.waitDialog = null;
1051 }
1052 }
1053 }
1054 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001055 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001056 if (mDidDexOpt) {
1057 mDidDexOpt = false;
1058 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1059 nmsg.obj = msg.obj;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001060 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001061 return;
1062 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001063 mServices.serviceTimeout((ProcessRecord)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001064 } break;
1065 case UPDATE_TIME_ZONE: {
1066 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001067 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1068 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 if (r.thread != null) {
1070 try {
1071 r.thread.updateTimeZone();
1072 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001073 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001074 }
1075 }
1076 }
1077 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001078 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001079 case CLEAR_DNS_CACHE: {
1080 synchronized (ActivityManagerService.this) {
1081 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1082 ProcessRecord r = mLruProcesses.get(i);
1083 if (r.thread != null) {
1084 try {
1085 r.thread.clearDnsCache();
1086 } catch (RemoteException ex) {
1087 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1088 }
1089 }
1090 }
1091 }
1092 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001093 case UPDATE_HTTP_PROXY: {
1094 ProxyProperties proxy = (ProxyProperties)msg.obj;
1095 String host = "";
1096 String port = "";
1097 String exclList = "";
1098 if (proxy != null) {
1099 host = proxy.getHost();
1100 port = Integer.toString(proxy.getPort());
1101 exclList = proxy.getExclusionList();
1102 }
1103 synchronized (ActivityManagerService.this) {
1104 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1105 ProcessRecord r = mLruProcesses.get(i);
1106 if (r.thread != null) {
1107 try {
1108 r.thread.setHttpProxy(host, port, exclList);
1109 } catch (RemoteException ex) {
1110 Slog.w(TAG, "Failed to update http proxy for: " +
1111 r.info.processName);
1112 }
1113 }
1114 }
1115 }
1116 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 case SHOW_UID_ERROR_MSG: {
Joe Onorato54a4a412011-11-02 20:50:08 -07001118 String title = "System UIDs Inconsistent";
1119 String text = "UIDs on the system are inconsistent, you need to wipe your"
1120 + " data partition or your device will be unstable.";
1121 Log.e(TAG, title + ": " + text);
1122 if (mShowDialogs) {
1123 // XXX This is a temporary dialog, no need to localize.
1124 AlertDialog d = new BaseErrorDialog(mContext);
1125 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1126 d.setCancelable(false);
1127 d.setTitle(title);
1128 d.setMessage(text);
1129 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1130 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1131 mUidAlert = d;
1132 d.show();
1133 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 } break;
1135 case IM_FEELING_LUCKY_MSG: {
1136 if (mUidAlert != null) {
1137 mUidAlert.dismiss();
1138 mUidAlert = null;
1139 }
1140 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001142 if (mDidDexOpt) {
1143 mDidDexOpt = false;
1144 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1145 nmsg.obj = msg.obj;
1146 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1147 return;
1148 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 ProcessRecord app = (ProcessRecord)msg.obj;
1150 synchronized (ActivityManagerService.this) {
1151 processStartTimedOutLocked(app);
1152 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001153 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001154 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1155 synchronized (ActivityManagerService.this) {
1156 doPendingActivityLaunchesLocked(true);
1157 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001158 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001159 case KILL_APPLICATION_MSG: {
1160 synchronized (ActivityManagerService.this) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001161 int appid = msg.arg1;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001162 boolean restart = (msg.arg2 == 1);
1163 String pkg = (String) msg.obj;
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001164 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1165 UserHandle.USER_ALL);
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001166 }
1167 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001168 case FINALIZE_PENDING_INTENT_MSG: {
1169 ((PendingIntentRecord)msg.obj).completeFinalize();
1170 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001171 case POST_HEAVY_NOTIFICATION_MSG: {
1172 INotificationManager inm = NotificationManager.getService();
1173 if (inm == null) {
1174 return;
1175 }
1176
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001177 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001178 ProcessRecord process = root.app;
1179 if (process == null) {
1180 return;
1181 }
1182
1183 try {
1184 Context context = mContext.createPackageContext(process.info.packageName, 0);
1185 String text = mContext.getString(R.string.heavy_weight_notification,
1186 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1187 Notification notification = new Notification();
1188 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1189 notification.when = 0;
1190 notification.flags = Notification.FLAG_ONGOING_EVENT;
1191 notification.tickerText = text;
1192 notification.defaults = 0; // please be quiet
1193 notification.sound = null;
1194 notification.vibrate = null;
1195 notification.setLatestEventInfo(context, text,
1196 mContext.getText(R.string.heavy_weight_notification_detail),
Dianne Hackborn41203752012-08-31 14:05:51 -07001197 PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1198 PendingIntent.FLAG_CANCEL_CURRENT, null,
1199 new UserHandle(root.userId)));
Dianne Hackborn860755f2010-06-03 18:47:52 -07001200
1201 try {
1202 int[] outId = new int[1];
Dianne Hackborn41203752012-08-31 14:05:51 -07001203 inm.enqueueNotificationWithTag("android", null,
1204 R.string.heavy_weight_notification,
1205 notification, outId, root.userId);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001206 } catch (RuntimeException e) {
1207 Slog.w(ActivityManagerService.TAG,
1208 "Error showing notification for heavy-weight app", e);
1209 } catch (RemoteException e) {
1210 }
1211 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001212 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001213 }
1214 } break;
1215 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1216 INotificationManager inm = NotificationManager.getService();
1217 if (inm == null) {
1218 return;
1219 }
1220 try {
Dianne Hackborn41203752012-08-31 14:05:51 -07001221 inm.cancelNotificationWithTag("android", null,
1222 R.string.heavy_weight_notification, msg.arg1);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001223 } catch (RuntimeException e) {
1224 Slog.w(ActivityManagerService.TAG,
1225 "Error canceling notification for service", e);
1226 } catch (RemoteException e) {
1227 }
1228 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001229 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1230 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001231 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001232 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001233 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1234 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001235 }
1236 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001237 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1238 synchronized (ActivityManagerService.this) {
1239 ActivityRecord ar = (ActivityRecord)msg.obj;
1240 if (mCompatModeDialog != null) {
1241 if (mCompatModeDialog.mAppInfo.packageName.equals(
1242 ar.info.applicationInfo.packageName)) {
1243 return;
1244 }
1245 mCompatModeDialog.dismiss();
1246 mCompatModeDialog = null;
1247 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001248 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001249 if (mCompatModePackages.getPackageAskCompatModeLocked(
1250 ar.packageName)) {
1251 int mode = mCompatModePackages.computeCompatModeLocked(
1252 ar.info.applicationInfo);
1253 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1254 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1255 mCompatModeDialog = new CompatModeDialog(
1256 ActivityManagerService.this, mContext,
1257 ar.info.applicationInfo);
1258 mCompatModeDialog.show();
1259 }
1260 }
1261 }
1262 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001263 break;
1264 }
Dianne Hackborna93c2c12012-05-31 15:29:36 -07001265 case DISPATCH_PROCESSES_CHANGED: {
1266 dispatchProcessesChanged();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001267 break;
1268 }
1269 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001270 final int pid = msg.arg1;
1271 final int uid = msg.arg2;
1272 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001273 break;
1274 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001275 case REPORT_MEM_USAGE: {
1276 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1277 if (!isDebuggable) {
1278 return;
1279 }
1280 synchronized (ActivityManagerService.this) {
1281 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001282 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1283 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001284 // avoid spamming.
1285 return;
1286 }
1287 mLastMemUsageReportTime = now;
1288 }
1289 Thread thread = new Thread() {
1290 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001291 StringBuilder dropBuilder = new StringBuilder(1024);
1292 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001293 StringWriter oomSw = new StringWriter();
1294 PrintWriter oomPw = new PrintWriter(oomSw);
1295 StringWriter catSw = new StringWriter();
1296 PrintWriter catPw = new PrintWriter(catSw);
1297 String[] emptyArgs = new String[] { };
1298 StringBuilder tag = new StringBuilder(128);
1299 StringBuilder stack = new StringBuilder(128);
1300 tag.append("Low on memory -- ");
1301 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1302 tag, stack);
1303 dropBuilder.append(stack);
1304 dropBuilder.append('\n');
1305 dropBuilder.append('\n');
1306 String oomString = oomSw.toString();
1307 dropBuilder.append(oomString);
1308 dropBuilder.append('\n');
1309 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001310 try {
1311 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1312 "procrank", });
1313 final InputStreamReader converter = new InputStreamReader(
1314 proc.getInputStream());
1315 BufferedReader in = new BufferedReader(converter);
1316 String line;
1317 while (true) {
1318 line = in.readLine();
1319 if (line == null) {
1320 break;
1321 }
1322 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001323 logBuilder.append(line);
1324 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001325 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001326 dropBuilder.append(line);
1327 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001328 }
1329 converter.close();
1330 } catch (IOException e) {
1331 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001332 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001333 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001334 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001335 catPw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001336 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1337 false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001338 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001339 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001340 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001341 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001342 addErrorToDropBox("lowmem", null, "system_server", null,
1343 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001344 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001345 synchronized (ActivityManagerService.this) {
1346 long now = SystemClock.uptimeMillis();
1347 if (mLastMemUsageReportTime < now) {
1348 mLastMemUsageReportTime = now;
1349 }
1350 }
1351 }
1352 };
1353 thread.start();
1354 break;
1355 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001356 case REPORT_USER_SWITCH_MSG: {
1357 dispatchUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1358 break;
1359 }
1360 case CONTINUE_USER_SWITCH_MSG: {
1361 continueUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1362 break;
1363 }
1364 case USER_SWITCH_TIMEOUT_MSG: {
1365 timeoutUserSwitch((UserStartedState)msg.obj, msg.arg1, msg.arg2);
1366 break;
1367 }
Christopher Tate73c2aee2012-03-15 16:27:14 -07001368 case IMMERSIVE_MODE_LOCK_MSG: {
1369 final boolean nextState = (msg.arg1 != 0);
1370 if (mUpdateLock.isHeld() != nextState) {
1371 if (DEBUG_IMMERSIVE) {
1372 final ActivityRecord r = (ActivityRecord) msg.obj;
1373 Slog.d(TAG, "Applying new update lock state '" + nextState + "' for " + r);
1374 }
1375 if (nextState) {
1376 mUpdateLock.acquire();
1377 } else {
1378 mUpdateLock.release();
1379 }
1380 }
1381 break;
1382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 }
1384 }
1385 };
1386
1387 public static void setSystemProcess() {
1388 try {
1389 ActivityManagerService m = mSelf;
1390
Dianne Hackborna573f6a2012-02-09 16:12:18 -08001391 ServiceManager.addService("activity", m, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001393 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
Jeff Brown6754ba22011-12-14 20:20:01 -08001394 ServiceManager.addService("dbinfo", new DbBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 if (MONITOR_CPU_USAGE) {
1396 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1397 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 ServiceManager.addService("permission", new PermissionController(m));
1399
1400 ApplicationInfo info =
1401 mSelf.mContext.getPackageManager().getApplicationInfo(
Amith Yamasani483f3b02012-03-13 16:08:00 -07001402 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001403 mSystemThread.installSystemApplicationInfo(info);
1404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 synchronized (mSelf) {
1406 ProcessRecord app = mSelf.newProcessRecordLocked(
1407 mSystemThread.getApplicationThread(), info,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001408 info.processName, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001410 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001411 app.maxAdj = ProcessList.SYSTEM_ADJ;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001412 mSelf.mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 synchronized (mSelf.mPidsSelfLocked) {
1414 mSelf.mPidsSelfLocked.put(app.pid, app);
1415 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001416 mSelf.updateLruProcessLocked(app, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 }
1418 } catch (PackageManager.NameNotFoundException e) {
1419 throw new RuntimeException(
1420 "Unable to find android system package", e);
1421 }
1422 }
1423
1424 public void setWindowManager(WindowManagerService wm) {
1425 mWindowManager = wm;
1426 }
1427
1428 public static final Context main(int factoryTest) {
1429 AThread thr = new AThread();
1430 thr.start();
1431
1432 synchronized (thr) {
1433 while (thr.mService == null) {
1434 try {
1435 thr.wait();
1436 } catch (InterruptedException e) {
1437 }
1438 }
1439 }
1440
1441 ActivityManagerService m = thr.mService;
1442 mSelf = m;
1443 ActivityThread at = ActivityThread.systemMain();
1444 mSystemThread = at;
1445 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001446 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001447 m.mContext = context;
1448 m.mFactoryTest = factoryTest;
Zoran Marcetaf958b322012-08-09 20:27:12 +09001449 m.mMainStack = new ActivityStack(m, context, true, thr.mLooper);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450
1451 m.mBatteryStatsService.publish(context);
1452 m.mUsageStatsService.publish(context);
1453
1454 synchronized (thr) {
1455 thr.mReady = true;
1456 thr.notifyAll();
1457 }
1458
1459 m.startRunning(null, null, null, null);
1460
1461 return context;
1462 }
1463
1464 public static ActivityManagerService self() {
1465 return mSelf;
1466 }
1467
1468 static class AThread extends Thread {
1469 ActivityManagerService mService;
Zoran Marcetaf958b322012-08-09 20:27:12 +09001470 Looper mLooper;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 boolean mReady = false;
1472
1473 public AThread() {
1474 super("ActivityManager");
1475 }
1476
1477 public void run() {
1478 Looper.prepare();
1479
1480 android.os.Process.setThreadPriority(
1481 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001482 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483
1484 ActivityManagerService m = new ActivityManagerService();
1485
1486 synchronized (this) {
1487 mService = m;
Zoran Marcetaf958b322012-08-09 20:27:12 +09001488 mLooper = Looper.myLooper();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 notifyAll();
1490 }
1491
1492 synchronized (this) {
1493 while (!mReady) {
1494 try {
1495 wait();
1496 } catch (InterruptedException e) {
1497 }
1498 }
1499 }
1500
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001501 // For debug builds, log event loop stalls to dropbox for analysis.
1502 if (StrictMode.conditionallyEnableDebugLogging()) {
1503 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1504 }
1505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001506 Looper.loop();
1507 }
1508 }
1509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 static class MemBinder extends Binder {
1511 ActivityManagerService mActivityManagerService;
1512 MemBinder(ActivityManagerService activityManagerService) {
1513 mActivityManagerService = activityManagerService;
1514 }
1515
1516 @Override
1517 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001518 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1519 != PackageManager.PERMISSION_GRANTED) {
1520 pw.println("Permission Denial: can't dump meminfo from from pid="
1521 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1522 + " without permission " + android.Manifest.permission.DUMP);
1523 return;
1524 }
1525
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001526 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001527 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001528 }
1529 }
1530
Chet Haase9c1e23b2011-03-24 10:51:31 -07001531 static class GraphicsBinder extends Binder {
1532 ActivityManagerService mActivityManagerService;
1533 GraphicsBinder(ActivityManagerService activityManagerService) {
1534 mActivityManagerService = activityManagerService;
1535 }
1536
1537 @Override
1538 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001539 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1540 != PackageManager.PERMISSION_GRANTED) {
1541 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1542 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1543 + " without permission " + android.Manifest.permission.DUMP);
1544 return;
1545 }
1546
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001547 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001548 }
1549 }
1550
Jeff Brown6754ba22011-12-14 20:20:01 -08001551 static class DbBinder extends Binder {
1552 ActivityManagerService mActivityManagerService;
1553 DbBinder(ActivityManagerService activityManagerService) {
1554 mActivityManagerService = activityManagerService;
1555 }
1556
1557 @Override
1558 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1559 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1560 != PackageManager.PERMISSION_GRANTED) {
1561 pw.println("Permission Denial: can't dump dbinfo from from pid="
1562 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1563 + " without permission " + android.Manifest.permission.DUMP);
1564 return;
1565 }
1566
1567 mActivityManagerService.dumpDbInfo(fd, pw, args);
1568 }
1569 }
1570
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 static class CpuBinder extends Binder {
1572 ActivityManagerService mActivityManagerService;
1573 CpuBinder(ActivityManagerService activityManagerService) {
1574 mActivityManagerService = activityManagerService;
1575 }
1576
1577 @Override
1578 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001579 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1580 != PackageManager.PERMISSION_GRANTED) {
1581 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1582 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1583 + " without permission " + android.Manifest.permission.DUMP);
1584 return;
1585 }
1586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001588 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1589 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1590 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 }
1592 }
1593 }
1594
1595 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001596 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001597
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001598 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1599 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1600 mBroadcastQueues[0] = mFgBroadcastQueue;
1601 mBroadcastQueues[1] = mBgBroadcastQueue;
1602
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001603 mServices = new ActiveServices(this);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001604 mProviderMap = new ProviderMap(this);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 File dataDir = Environment.getDataDirectory();
1607 File systemDir = new File(dataDir, "system");
1608 systemDir.mkdirs();
1609 mBatteryStatsService = new BatteryStatsService(new File(
1610 systemDir, "batterystats.bin").toString());
1611 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001612 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001613 mOnBattery = DEBUG_POWER ? true
1614 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001615 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001616
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001617 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001618 systemDir, "usagestats").toString());
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001619 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001621 // User 0 is the first and only user that runs at boot.
1622 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001623 mUserLru.add(Integer.valueOf(0));
Dianne Hackbornc72fc672012-09-20 13:12:03 -07001624 updateStartedUserArrayLocked();
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001625
Jack Palevichb90d28c2009-07-22 15:35:24 -07001626 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1627 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1628
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001629 mConfiguration.setToDefaults();
Fabrice Di Meglio5f797992012-06-15 20:16:41 -07001630 mConfiguration.setLocale(Locale.getDefault());
1631
Dianne Hackborn813075a62011-11-14 17:45:19 -08001632 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001633 mProcessStats.init();
1634
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001635 mCompatModePackages = new CompatModePackages(this, systemDir);
1636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 // Add ourself to the Watchdog monitors.
1638 Watchdog.getInstance().addMonitor(this);
1639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001640 mProcessStatsThread = new Thread("ProcessStats") {
1641 public void run() {
1642 while (true) {
1643 try {
1644 try {
1645 synchronized(this) {
1646 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001647 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001649 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001650 // + ", write delay=" + nextWriteDelay);
1651 if (nextWriteDelay < nextCpuDelay) {
1652 nextCpuDelay = nextWriteDelay;
1653 }
1654 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001655 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 this.wait(nextCpuDelay);
1657 }
1658 }
1659 } catch (InterruptedException e) {
1660 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001661 updateCpuStatsNow();
1662 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001663 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664 }
1665 }
1666 }
1667 };
1668 mProcessStatsThread.start();
1669 }
1670
1671 @Override
1672 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1673 throws RemoteException {
Dianne Hackborna53de062012-05-08 18:53:51 -07001674 if (code == SYSPROPS_TRANSACTION) {
1675 // We need to tell all apps about the system property change.
1676 ArrayList<IBinder> procs = new ArrayList<IBinder>();
1677 synchronized(this) {
1678 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1679 final int NA = apps.size();
1680 for (int ia=0; ia<NA; ia++) {
1681 ProcessRecord app = apps.valueAt(ia);
1682 if (app.thread != null) {
1683 procs.add(app.thread.asBinder());
1684 }
1685 }
1686 }
1687 }
1688
1689 int N = procs.size();
1690 for (int i=0; i<N; i++) {
1691 Parcel data2 = Parcel.obtain();
1692 try {
1693 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1694 } catch (RemoteException e) {
1695 }
1696 data2.recycle();
1697 }
1698 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 try {
1700 return super.onTransact(code, data, reply, flags);
1701 } catch (RuntimeException e) {
1702 // The activity manager only throws security exceptions, so let's
1703 // log all others.
1704 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001705 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001706 }
1707 throw e;
1708 }
1709 }
1710
1711 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001712 final long now = SystemClock.uptimeMillis();
1713 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1714 return;
1715 }
1716 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1717 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001718 mProcessStatsThread.notify();
1719 }
1720 }
1721 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 void updateCpuStatsNow() {
1724 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001725 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001726 final long now = SystemClock.uptimeMillis();
1727 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001728
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001729 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001730 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1731 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001732 haveNewCpuStats = true;
1733 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001734 //Slog.i(TAG, mProcessStats.printCurrentState());
1735 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736 // + mProcessStats.getTotalCpuPercent() + "%");
1737
Joe Onorato8a9b2202010-02-26 18:56:32 -08001738 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001739 if ("true".equals(SystemProperties.get("events.cpu"))) {
1740 int user = mProcessStats.getLastUserTime();
1741 int system = mProcessStats.getLastSystemTime();
1742 int iowait = mProcessStats.getLastIoWaitTime();
1743 int irq = mProcessStats.getLastIrqTime();
1744 int softIrq = mProcessStats.getLastSoftIrqTime();
1745 int idle = mProcessStats.getLastIdleTime();
1746
1747 int total = user + system + iowait + irq + softIrq + idle;
1748 if (total == 0) total = 1;
1749
Doug Zongker2bec3d42009-12-04 12:52:44 -08001750 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 ((user+system+iowait+irq+softIrq) * 100) / total,
1752 (user * 100) / total,
1753 (system * 100) / total,
1754 (iowait * 100) / total,
1755 (irq * 100) / total,
1756 (softIrq * 100) / total);
1757 }
1758 }
1759
Amith Yamasanie43530a2009-08-21 13:11:37 -07001760 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001761 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001762 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001763 synchronized(mPidsSelfLocked) {
1764 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001765 if (mOnBattery) {
1766 int perc = bstats.startAddingCpuLocked();
1767 int totalUTime = 0;
1768 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001769 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001771 ProcessStats.Stats st = mProcessStats.getStats(i);
1772 if (!st.working) {
1773 continue;
1774 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001775 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001776 int otherUTime = (st.rel_utime*perc)/100;
1777 int otherSTime = (st.rel_stime*perc)/100;
1778 totalUTime += otherUTime;
1779 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 if (pr != null) {
1781 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001782 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1783 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001784 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001785 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001786 } else {
1787 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001788 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001789 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001790 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1791 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001792 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001794 }
1795 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001796 bstats.finishAddingCpuLocked(perc, totalUTime,
1797 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 }
1799 }
1800 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001802 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1803 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001804 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001805 }
1806 }
1807 }
1808 }
1809
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001810 @Override
1811 public void batteryNeedsCpuUpdate() {
1812 updateCpuStatsNow();
1813 }
1814
1815 @Override
1816 public void batteryPowerChanged(boolean onBattery) {
1817 // When plugging in, update the CPU stats first before changing
1818 // the plug state.
1819 updateCpuStatsNow();
1820 synchronized (this) {
1821 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001822 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001823 }
1824 }
1825 }
1826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 /**
1828 * Initialize the application bind args. These are passed to each
1829 * process when the bindApplication() IPC is sent to the process. They're
1830 * lazily setup to make sure the services are running when they're asked for.
1831 */
1832 private HashMap<String, IBinder> getCommonServicesLocked() {
1833 if (mAppBindArgs == null) {
1834 mAppBindArgs = new HashMap<String, IBinder>();
1835
1836 // Setup the application init args
1837 mAppBindArgs.put("package", ServiceManager.getService("package"));
1838 mAppBindArgs.put("window", ServiceManager.getService("window"));
1839 mAppBindArgs.put(Context.ALARM_SERVICE,
1840 ServiceManager.getService(Context.ALARM_SERVICE));
1841 }
1842 return mAppBindArgs;
1843 }
1844
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001845 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001846 if (mFocusedActivity != r) {
1847 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001848 if (r != null) {
1849 mWindowManager.setFocusedApp(r.appToken, true);
1850 }
Christopher Tate73c2aee2012-03-15 16:27:14 -07001851 applyUpdateLockStateLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 }
1853 }
1854
Christopher Tate73c2aee2012-03-15 16:27:14 -07001855 final void applyUpdateLockStateLocked(ActivityRecord r) {
1856 // Modifications to the UpdateLock state are done on our handler, outside
1857 // the activity manager's locks. The new state is determined based on the
1858 // state *now* of the relevant activity record. The object is passed to
1859 // the handler solely for logging detail, not to be consulted/modified.
1860 final boolean nextState = r != null && r.immersive;
1861 mHandler.sendMessage(
1862 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
1863 }
1864
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001865 private final void updateLruProcessInternalLocked(ProcessRecord app, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001866 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001867 int lrui = mLruProcesses.indexOf(app);
1868 if (lrui >= 0) mLruProcesses.remove(lrui);
1869
1870 int i = mLruProcesses.size()-1;
1871 int skipTop = 0;
1872
Dianne Hackborn906497c2010-05-10 15:57:38 -07001873 app.lruSeq = mLruSeq;
1874
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001875 // compute the new weight for this process.
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001876 app.lastActivityTime = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001877 if (app.activities.size() > 0) {
1878 // If this process has activities, we more strongly want to keep
1879 // it around.
1880 app.lruWeight = app.lastActivityTime;
1881 } else if (app.pubProviders.size() > 0) {
1882 // If this process contains content providers, we want to keep
1883 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001884 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001885 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001886 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001887 } else {
1888 // If this process doesn't have activities, we less strongly
1889 // want to keep it around, and generally want to avoid getting
1890 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001891 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001892 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001893 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001894 }
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001895
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001896 while (i >= 0) {
1897 ProcessRecord p = mLruProcesses.get(i);
1898 // If this app shouldn't be in front of the first N background
1899 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001900 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001901 skipTop--;
1902 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001903 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001904 mLruProcesses.add(i+1, app);
1905 break;
1906 }
1907 i--;
1908 }
1909 if (i < 0) {
1910 mLruProcesses.add(0, app);
1911 }
1912
Dianne Hackborn906497c2010-05-10 15:57:38 -07001913 // If the app is currently using a content provider or service,
1914 // bump those processes as well.
1915 if (app.connections.size() > 0) {
1916 for (ConnectionRecord cr : app.connections) {
1917 if (cr.binding != null && cr.binding.service != null
1918 && cr.binding.service.app != null
1919 && cr.binding.service.app.lruSeq != mLruSeq) {
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001920 updateLruProcessInternalLocked(cr.binding.service.app, i+1);
Dianne Hackborn906497c2010-05-10 15:57:38 -07001921 }
1922 }
1923 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001924 for (int j=app.conProviders.size()-1; j>=0; j--) {
1925 ContentProviderRecord cpr = app.conProviders.get(j).provider;
1926 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001927 updateLruProcessInternalLocked(cpr.proc, i+1);
Dianne Hackborn906497c2010-05-10 15:57:38 -07001928 }
1929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001930 }
1931
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001932 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001933 boolean oomAdj) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07001934 mLruSeq++;
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001935 updateLruProcessInternalLocked(app, 0);
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001936
1937 //Slog.i(TAG, "Putting proc to front: " + app.processName);
1938 if (oomAdj) {
1939 updateOomAdjLocked();
1940 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001941 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001942
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001943 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001944 String processName, int uid) {
Amith Yamasania4a54e22012-04-16 15:44:19 -07001945 if (uid == Process.SYSTEM_UID) {
Amith Yamasani0184ce92012-03-28 22:41:41 -07001946 // The system gets to run in any process. If there are multiple
1947 // processes with the same uid, just pick the first (this
1948 // should never happen).
1949 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1950 processName);
Amith Yamasania4a54e22012-04-16 15:44:19 -07001951 if (procs == null) return null;
1952 final int N = procs.size();
1953 for (int i = 0; i < N; i++) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001954 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
Amith Yamasania4a54e22012-04-16 15:44:19 -07001955 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 }
1957 ProcessRecord proc = mProcessNames.get(processName, uid);
1958 return proc;
1959 }
1960
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001961 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001962 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001963 try {
1964 if (pm.performDexOpt(packageName)) {
1965 mDidDexOpt = true;
1966 }
1967 } catch (RemoteException e) {
1968 }
1969 }
1970
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001971 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 int transit = mWindowManager.getPendingAppTransition();
Craig Mautner4b71aa12012-12-27 17:20:01 -08001973 return transit == AppTransition.TRANSIT_ACTIVITY_OPEN
1974 || transit == AppTransition.TRANSIT_TASK_OPEN
1975 || transit == AppTransition.TRANSIT_TASK_TO_FRONT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001976 }
1977
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001978 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001980 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1981 boolean isolated) {
1982 ProcessRecord app;
1983 if (!isolated) {
1984 app = getProcessRecordLocked(processName, info.uid);
1985 } else {
1986 // If this is an isolated process, it can't re-use an existing process.
1987 app = null;
1988 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 // We don't have to do anything more if:
1990 // (1) There is an existing application record; and
1991 // (2) The caller doesn't think it is dead, OR there is no thread
1992 // object attached to it so we know it couldn't have crashed; and
1993 // (3) There is a pid assigned to it, so it is either starting or
1994 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001995 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001996 + " app=" + app + " knownToBeDead=" + knownToBeDead
1997 + " thread=" + (app != null ? app.thread : null)
1998 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001999 if (app != null && app.pid > 0) {
2000 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08002001 // We already have the app running, or are waiting for it to
2002 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002003 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07002004 // If this is a new package in the process, add the package to the list
2005 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002006 return app;
2007 } else {
2008 // An application record is attached to a previous process,
2009 // clean it up now.
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002010 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002011 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01002012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01002014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 String hostingNameStr = hostingName != null
2016 ? hostingName.flattenToShortString() : null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002017
2018 if (!isolated) {
2019 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
2020 // If we are in the background, then check to see if this process
2021 // is bad. If so, we will just silently fail.
2022 if (mBadProcesses.get(info.processName, info.uid) != null) {
2023 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
2024 + "/" + info.processName);
2025 return null;
2026 }
2027 } else {
2028 // When the user is explicitly starting a process, then clear its
2029 // crash count so that we won't make it bad until they see at
2030 // least one crash dialog again, and make the process good again
2031 // if it had been bad.
2032 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002033 + "/" + info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002034 mProcessCrashTimes.remove(info.processName, info.uid);
2035 if (mBadProcesses.get(info.processName, info.uid) != null) {
Dianne Hackbornb12e1352012-09-26 11:39:20 -07002036 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
2037 UserHandle.getUserId(info.uid), info.uid,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002038 info.processName);
2039 mBadProcesses.remove(info.processName, info.uid);
2040 if (app != null) {
2041 app.bad = false;
2042 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002043 }
2044 }
2045 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002046
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002048 app = newProcessRecordLocked(null, info, processName, isolated);
2049 if (app == null) {
2050 Slog.w(TAG, "Failed making new process record for "
2051 + processName + "/" + info.uid + " isolated=" + isolated);
2052 return null;
2053 }
2054 mProcessNames.put(processName, app.uid, app);
2055 if (isolated) {
2056 mIsolatedProcesses.put(app.uid, app);
2057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002058 } else {
2059 // If this is a new package in the process, add the package to the list
2060 app.addPackage(info.packageName);
2061 }
2062
2063 // If the system is not ready yet, then hold off on starting this
2064 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002065 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002066 && !isAllowedWhileBooting(info)
2067 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 if (!mProcessesOnHold.contains(app)) {
2069 mProcessesOnHold.add(app);
2070 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002071 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 return app;
2073 }
2074
2075 startProcessLocked(app, hostingType, hostingNameStr);
2076 return (app.pid != 0) ? app : null;
2077 }
2078
Dianne Hackborn9acc0302009-08-25 00:27:12 -07002079 boolean isAllowedWhileBooting(ApplicationInfo ai) {
2080 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
2081 }
2082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 private final void startProcessLocked(ProcessRecord app,
2084 String hostingType, String hostingNameStr) {
2085 if (app.pid > 0 && app.pid != MY_PID) {
2086 synchronized (mPidsSelfLocked) {
2087 mPidsSelfLocked.remove(app.pid);
2088 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
2089 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002090 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002091 }
2092
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07002093 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
2094 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002095 mProcessesOnHold.remove(app);
2096
2097 updateCpuStats();
2098
2099 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
2100 mProcDeaths[0] = 0;
2101
2102 try {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002103 int uid = app.uid;
Amith Yamasani742a6712011-05-04 14:49:28 -07002104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002105 int[] gids = null;
Jeff Sharkey5b1ada22012-08-14 18:47:09 -07002106 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002107 if (!app.isolated) {
Kenny Roote091f222012-09-11 15:01:26 -07002108 int[] permGids = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002109 try {
Jeff Sharkey5b1ada22012-08-14 18:47:09 -07002110 final PackageManager pm = mContext.getPackageManager();
Kenny Roote091f222012-09-11 15:01:26 -07002111 permGids = pm.getPackageGids(app.info.packageName);
Jeff Sharkeye217ee42012-08-28 16:23:01 -07002112
2113 if (Environment.isExternalStorageEmulated()) {
2114 if (pm.checkPermission(
2115 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2116 app.info.packageName) == PERMISSION_GRANTED) {
2117 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2118 } else {
2119 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2120 }
2121 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002122 } catch (PackageManager.NameNotFoundException e) {
2123 Slog.w(TAG, "Unable to retrieve gids", e);
2124 }
Kenny Roote091f222012-09-11 15:01:26 -07002125
2126 /*
2127 * Add shared application GID so applications can share some
2128 * resources like shared libraries
2129 */
2130 if (permGids == null) {
2131 gids = new int[1];
2132 } else {
2133 gids = new int[permGids.length + 1];
2134 System.arraycopy(permGids, 0, gids, 1, permGids.length);
2135 }
2136 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 }
2138 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2139 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2140 && mTopComponent != null
2141 && app.processName.equals(mTopComponent.getPackageName())) {
2142 uid = 0;
2143 }
2144 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2145 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2146 uid = 0;
2147 }
2148 }
2149 int debugFlags = 0;
2150 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2151 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07002152 // Also turn on CheckJNI for debuggable apps. It's quite
2153 // awkward to turn on otherwise.
2154 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08002156 // Run the app in safe mode if its manifest requests so or the
2157 // system is booted in safe mode.
2158 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2159 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08002160 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2161 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002162 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2163 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2164 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07002165 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2166 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002168 if ("1".equals(SystemProperties.get("debug.assert"))) {
2169 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2170 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07002171
2172 // Start the process. It will either succeed and return a result containing
2173 // the PID of the new process, or else throw a RuntimeException.
2174 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Jeff Sharkey5b1ada22012-08-14 18:47:09 -07002175 app.processName, uid, uid, gids, debugFlags, mountExternal,
Stephen Smalley83d9eda2012-01-13 08:34:17 -05002176 app.info.targetSdkVersion, null, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002177
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2179 synchronized (bs) {
2180 if (bs.isOnBattery()) {
2181 app.batteryStats.incStartsLocked();
2182 }
2183 }
2184
Dianne Hackbornb12e1352012-09-26 11:39:20 -07002185 EventLog.writeEvent(EventLogTags.AM_PROC_START,
2186 UserHandle.getUserId(uid), startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002187 app.processName, hostingType,
2188 hostingNameStr != null ? hostingNameStr : "");
2189
2190 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07002191 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 }
2193
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002194 StringBuilder buf = mStringBuilder;
2195 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 buf.append("Start proc ");
2197 buf.append(app.processName);
2198 buf.append(" for ");
2199 buf.append(hostingType);
2200 if (hostingNameStr != null) {
2201 buf.append(" ");
2202 buf.append(hostingNameStr);
2203 }
2204 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07002205 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002206 buf.append(" uid=");
2207 buf.append(uid);
2208 buf.append(" gids={");
2209 if (gids != null) {
2210 for (int gi=0; gi<gids.length; gi++) {
2211 if (gi != 0) buf.append(", ");
2212 buf.append(gids[gi]);
2213
2214 }
2215 }
2216 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002217 Slog.i(TAG, buf.toString());
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002218 app.setPid(startResult.pid);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002219 app.usingWrapper = startResult.usingWrapper;
2220 app.removed = false;
2221 synchronized (mPidsSelfLocked) {
2222 this.mPidsSelfLocked.put(startResult.pid, app);
2223 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2224 msg.obj = app;
2225 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2226 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002227 }
2228 } catch (RuntimeException e) {
2229 // XXX do better error recovery.
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002230 app.setPid(0);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002231 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002232 }
2233 }
2234
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002235 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002236 if (resumed) {
2237 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2238 } else {
2239 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2240 }
2241 }
2242
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07002243 boolean startHomeActivityLocked(int userId) {
Mike Lockwooda8f767a2011-08-31 14:32:37 -04002244 if (mHeadless) {
2245 // Added because none of the other calls to ensureBootCompleted seem to fire
2246 // when running headless.
2247 ensureBootCompleted();
2248 return false;
2249 }
2250
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002251 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2252 && mTopAction == null) {
2253 // We are running in factory test mode, but unable to find
2254 // the factory test app, so just sit around displaying the
2255 // error message and don't try to start anything.
2256 return false;
2257 }
2258 Intent intent = new Intent(
2259 mTopAction,
2260 mTopData != null ? Uri.parse(mTopData) : null);
2261 intent.setComponent(mTopComponent);
2262 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2263 intent.addCategory(Intent.CATEGORY_HOME);
2264 }
2265 ActivityInfo aInfo =
Amith Yamasani259d5e52012-08-31 15:11:01 -07002266 resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002267 if (aInfo != null) {
2268 intent.setComponent(new ComponentName(
2269 aInfo.applicationInfo.packageName, aInfo.name));
2270 // Don't do this if the home app is currently being
2271 // instrumented.
Amith Yamasani742a6712011-05-04 14:49:28 -07002272 aInfo = new ActivityInfo(aInfo);
2273 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002274 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2275 aInfo.applicationInfo.uid);
2276 if (app == null || app.instrumentationClass == null) {
2277 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborna4972e92012-03-14 10:38:05 -07002278 mMainStack.startActivityLocked(null, intent, null, aInfo,
2279 null, null, 0, 0, 0, 0, null, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002280 }
2281 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002282
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002283 return true;
2284 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002285
Amith Yamasani259d5e52012-08-31 15:11:01 -07002286 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
2287 ActivityInfo ai = null;
2288 ComponentName comp = intent.getComponent();
2289 try {
2290 if (comp != null) {
2291 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
2292 } else {
2293 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
2294 intent,
2295 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
2296 flags, userId);
2297
2298 if (info != null) {
2299 ai = info.activityInfo;
2300 }
2301 }
2302 } catch (RemoteException e) {
2303 // ignore
2304 }
2305
2306 return ai;
2307 }
2308
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002309 /**
2310 * Starts the "new version setup screen" if appropriate.
2311 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002312 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002313 // Only do this once per boot.
2314 if (mCheckedForSetup) {
2315 return;
2316 }
2317
2318 // We will show this screen if the current one is a different
2319 // version than the last one shown, and we are not running in
2320 // low-level factory test mode.
2321 final ContentResolver resolver = mContext.getContentResolver();
2322 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
Jeff Brownbf6f6f92012-09-25 15:03:20 -07002323 Settings.Global.getInt(resolver,
2324 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002325 mCheckedForSetup = true;
2326
2327 // See if we should be showing the platform update setup UI.
2328 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2329 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2330 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2331
2332 // We don't allow third party apps to replace this.
2333 ResolveInfo ri = null;
2334 for (int i=0; ris != null && i<ris.size(); i++) {
2335 if ((ris.get(i).activityInfo.applicationInfo.flags
2336 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2337 ri = ris.get(i);
2338 break;
2339 }
2340 }
2341
2342 if (ri != null) {
2343 String vers = ri.activityInfo.metaData != null
2344 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2345 : null;
2346 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2347 vers = ri.activityInfo.applicationInfo.metaData.getString(
2348 Intent.METADATA_SETUP_VERSION);
2349 }
2350 String lastVers = Settings.Secure.getString(
2351 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2352 if (vers != null && !vers.equals(lastVers)) {
2353 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2354 intent.setComponent(new ComponentName(
2355 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborna4972e92012-03-14 10:38:05 -07002356 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2357 null, null, 0, 0, 0, 0, null, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002358 }
2359 }
2360 }
2361 }
2362
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002363 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002364 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002365 }
2366
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002367 void enforceNotIsolatedCaller(String caller) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002368 if (UserHandle.isIsolated(Binder.getCallingUid())) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002369 throw new SecurityException("Isolated process not allowed to call " + caller);
2370 }
2371 }
2372
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002373 public int getFrontActivityScreenCompatMode() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002374 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002375 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002376 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2377 }
2378 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002379
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002380 public void setFrontActivityScreenCompatMode(int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002381 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2382 "setFrontActivityScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002383 synchronized (this) {
2384 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2385 }
2386 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002387
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002388 public int getPackageScreenCompatMode(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002389 enforceNotIsolatedCaller("getPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002390 synchronized (this) {
2391 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2392 }
2393 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002394
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002395 public void setPackageScreenCompatMode(String packageName, int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002396 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2397 "setPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002398 synchronized (this) {
2399 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002400 }
2401 }
2402
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002403 public boolean getPackageAskScreenCompat(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002404 enforceNotIsolatedCaller("getPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002405 synchronized (this) {
2406 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2407 }
2408 }
2409
2410 public void setPackageAskScreenCompat(String packageName, boolean ask) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002411 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2412 "setPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002413 synchronized (this) {
2414 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2415 }
2416 }
2417
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002418 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002419 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002420 updateUsageStats(r, true);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002421 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002422
Dianne Hackborna93c2c12012-05-31 15:29:36 -07002423 private void dispatchProcessesChanged() {
2424 int N;
2425 synchronized (this) {
2426 N = mPendingProcessChanges.size();
2427 if (mActiveProcessChanges.length < N) {
2428 mActiveProcessChanges = new ProcessChangeItem[N];
2429 }
2430 mPendingProcessChanges.toArray(mActiveProcessChanges);
2431 mAvailProcessChanges.addAll(mPendingProcessChanges);
2432 mPendingProcessChanges.clear();
2433 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2434 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07002435 int i = mProcessObservers.beginBroadcast();
2436 while (i > 0) {
2437 i--;
2438 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2439 if (observer != null) {
2440 try {
Dianne Hackborna93c2c12012-05-31 15:29:36 -07002441 for (int j=0; j<N; j++) {
2442 ProcessChangeItem item = mActiveProcessChanges[j];
2443 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2444 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2445 + item.pid + " uid=" + item.uid + ": "
2446 + item.foregroundActivities);
2447 observer.onForegroundActivitiesChanged(item.pid, item.uid,
2448 item.foregroundActivities);
2449 }
2450 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2451 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2452 + item.pid + " uid=" + item.uid + ": " + item.importance);
2453 observer.onImportanceChanged(item.pid, item.uid,
2454 item.importance);
2455 }
2456 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07002457 } catch (RemoteException e) {
2458 }
2459 }
2460 }
2461 mProcessObservers.finishBroadcast();
2462 }
2463
2464 private void dispatchProcessDied(int pid, int uid) {
2465 int i = mProcessObservers.beginBroadcast();
2466 while (i > 0) {
2467 i--;
2468 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2469 if (observer != null) {
2470 try {
2471 observer.onProcessDied(pid, uid);
2472 } catch (RemoteException e) {
2473 }
2474 }
2475 }
2476 mProcessObservers.finishBroadcast();
2477 }
2478
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002479 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002480 final int N = mPendingActivityLaunches.size();
2481 if (N <= 0) {
2482 return;
2483 }
2484 for (int i=0; i<N; i++) {
2485 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002486 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002487 pal.startFlags, doResume && i == (N-1), null);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002488 }
2489 mPendingActivityLaunches.clear();
2490 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002491
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002492 public final int startActivity(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002493 Intent intent, String resolvedType, IBinder resultTo,
2494 String resultWho, int requestCode, int startFlags,
2495 String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
Amith Yamasani82644082012-08-03 13:09:11 -07002496 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002497 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
Amith Yamasani82644082012-08-03 13:09:11 -07002498 }
2499
2500 public final int startActivityAsUser(IApplicationThread caller,
2501 Intent intent, String resolvedType, IBinder resultTo,
2502 String resultWho, int requestCode, int startFlags,
2503 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002504 enforceNotIsolatedCaller("startActivity");
Dianne Hackborn139748f2012-09-24 11:36:57 -07002505 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Dianne Hackbornd8883992012-09-07 15:58:52 -07002506 false, true, "startActivity", null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002507 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002508 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2509 null, null, options, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002510 }
2511
2512 public final WaitResult startActivityAndWait(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002513 Intent intent, String resolvedType, IBinder resultTo,
2514 String resultWho, int requestCode, int startFlags, String profileFile,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002515 ParcelFileDescriptor profileFd, Bundle options, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002516 enforceNotIsolatedCaller("startActivityAndWait");
Dianne Hackborn139748f2012-09-24 11:36:57 -07002517 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002518 false, true, "startActivityAndWait", null);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002519 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002520 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002521 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
Dianne Hackborn41203752012-08-31 14:05:51 -07002522 res, null, options, UserHandle.getCallingUserId());
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002523 return res;
2524 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08002525
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002526 public final int startActivityWithConfig(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002527 Intent intent, String resolvedType, IBinder resultTo,
2528 String resultWho, int requestCode, int startFlags, Configuration config,
Dianne Hackborn41203752012-08-31 14:05:51 -07002529 Bundle options, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002530 enforceNotIsolatedCaller("startActivityWithConfig");
Dianne Hackborn139748f2012-09-24 11:36:57 -07002531 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Dianne Hackborn41203752012-08-31 14:05:51 -07002532 false, true, "startActivityWithConfig", null);
Amith Yamasani742a6712011-05-04 14:49:28 -07002533 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002534 resultTo, resultWho, requestCode, startFlags,
Dianne Hackborn41203752012-08-31 14:05:51 -07002535 null, null, null, config, options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002536 return ret;
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002537 }
2538
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002539 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002540 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002541 IBinder resultTo, String resultWho, int requestCode,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002542 int flagsMask, int flagsValues, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002543 enforceNotIsolatedCaller("startActivityIntentSender");
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002544 // Refuse possible leaked file descriptors
2545 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2546 throw new IllegalArgumentException("File descriptors passed in Intent");
2547 }
2548
2549 IIntentSender sender = intent.getTarget();
2550 if (!(sender instanceof PendingIntentRecord)) {
2551 throw new IllegalArgumentException("Bad PendingIntent object");
2552 }
2553
2554 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002555
2556 synchronized (this) {
2557 // If this is coming from the currently resumed activity, it is
2558 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002559 if (mMainStack.mResumedActivity != null
2560 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002561 Binder.getCallingUid()) {
2562 mAppSwitchesAllowedTime = 0;
2563 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002564 }
Dianne Hackborna4972e92012-03-14 10:38:05 -07002565 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2566 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
Amith Yamasani742a6712011-05-04 14:49:28 -07002567 return ret;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002568 }
2569
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002570 public boolean startNextMatchingActivity(IBinder callingActivity,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002571 Intent intent, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002572 // Refuse possible leaked file descriptors
2573 if (intent != null && intent.hasFileDescriptors() == true) {
2574 throw new IllegalArgumentException("File descriptors passed in Intent");
2575 }
2576
2577 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002578 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2579 if (r == null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002580 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002581 return false;
2582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002583 if (r.app == null || r.app.thread == null) {
2584 // The caller is not running... d'oh!
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002585 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002586 return false;
2587 }
2588 intent = new Intent(intent);
2589 // The caller is not allowed to change the data.
2590 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2591 // And we are resetting to find the next component...
2592 intent.setComponent(null);
2593
2594 ActivityInfo aInfo = null;
2595 try {
2596 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002597 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 intent, r.resolvedType,
Amith Yamasani483f3b02012-03-13 16:08:00 -07002599 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002600 UserHandle.getCallingUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601
2602 // Look for the original activity in the list...
2603 final int N = resolves != null ? resolves.size() : 0;
2604 for (int i=0; i<N; i++) {
2605 ResolveInfo rInfo = resolves.get(i);
2606 if (rInfo.activityInfo.packageName.equals(r.packageName)
2607 && rInfo.activityInfo.name.equals(r.info.name)) {
2608 // We found the current one... the next matching is
2609 // after it.
2610 i++;
2611 if (i<N) {
2612 aInfo = resolves.get(i).activityInfo;
2613 }
2614 break;
2615 }
2616 }
2617 } catch (RemoteException e) {
2618 }
2619
2620 if (aInfo == null) {
2621 // Nobody who is next!
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002622 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002623 return false;
2624 }
2625
2626 intent.setComponent(new ComponentName(
2627 aInfo.applicationInfo.packageName, aInfo.name));
2628 intent.setFlags(intent.getFlags()&~(
2629 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2630 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2631 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2632 Intent.FLAG_ACTIVITY_NEW_TASK));
2633
2634 // Okay now we need to start the new activity, replacing the
2635 // currently running activity. This is a little tricky because
2636 // we want to start the new one as if the current one is finished,
2637 // but not finish the current one first so that there is no flicker.
2638 // And thus...
2639 final boolean wasFinishing = r.finishing;
2640 r.finishing = true;
2641
2642 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002643 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002644 final String resultWho = r.resultWho;
2645 final int requestCode = r.requestCode;
2646 r.resultTo = null;
2647 if (resultTo != null) {
2648 resultTo.removeResultsLocked(r, resultWho, requestCode);
2649 }
2650
2651 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002652 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002653 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2654 resultWho, requestCode, -1, r.launchedFromUid, 0,
2655 options, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 Binder.restoreCallingIdentity(origId);
2657
2658 r.finishing = wasFinishing;
Dianne Hackborna4972e92012-03-14 10:38:05 -07002659 if (res != ActivityManager.START_SUCCESS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002660 return false;
2661 }
2662 return true;
2663 }
2664 }
2665
Dianne Hackborn41203752012-08-31 14:05:51 -07002666 final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 Intent intent, String resolvedType, IBinder resultTo,
Dianne Hackborn41203752012-08-31 14:05:51 -07002668 String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2669
Dianne Hackborn139748f2012-09-24 11:36:57 -07002670 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Dianne Hackborn41203752012-08-31 14:05:51 -07002671 false, true, "startActivityInPackage", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002672
Amith Yamasani742a6712011-05-04 14:49:28 -07002673 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002674 resultTo, resultWho, requestCode, startFlags,
Dianne Hackborn41203752012-08-31 14:05:51 -07002675 null, null, null, null, options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002676 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002677 }
2678
2679 public final int startActivities(IApplicationThread caller,
Amith Yamasaniea7e9152012-09-24 16:11:18 -07002680 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options,
2681 int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002682 enforceNotIsolatedCaller("startActivities");
Amith Yamasani16979ea2012-09-24 18:14:47 -07002683 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Amith Yamasaniea7e9152012-09-24 16:11:18 -07002684 false, true, "startActivity", null);
Amith Yamasani742a6712011-05-04 14:49:28 -07002685 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
Amith Yamasaniea7e9152012-09-24 16:11:18 -07002686 options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002687 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002688 }
2689
Dianne Hackborn41203752012-08-31 14:05:51 -07002690 final int startActivitiesInPackage(int uid,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002691 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
Dianne Hackborn41203752012-08-31 14:05:51 -07002692 Bundle options, int userId) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002693
Dianne Hackborn139748f2012-09-24 11:36:57 -07002694 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Dianne Hackborn41203752012-08-31 14:05:51 -07002695 false, true, "startActivityInPackage", null);
Amith Yamasani742a6712011-05-04 14:49:28 -07002696 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
Dianne Hackborn41203752012-08-31 14:05:51 -07002697 options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002698 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002699 }
2700
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002701 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002702 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002703 // Quick case: check if the top-most recent task is the same.
2704 if (N > 0 && mRecentTasks.get(0) == task) {
2705 return;
2706 }
2707 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002708 for (int i=0; i<N; i++) {
2709 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07002710 if (task.userId == tr.userId
2711 && ((task.affinity != null && task.affinity.equals(tr.affinity))
2712 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 mRecentTasks.remove(i);
2714 i--;
2715 N--;
2716 if (task.intent == null) {
2717 // If the new recent task we are adding is not fully
2718 // specified, then replace it with the existing recent task.
2719 task = tr;
2720 }
2721 }
2722 }
2723 if (N >= MAX_RECENT_TASKS) {
2724 mRecentTasks.remove(N-1);
2725 }
2726 mRecentTasks.add(0, task);
2727 }
2728
2729 public void setRequestedOrientation(IBinder token,
2730 int requestedOrientation) {
2731 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002732 ActivityRecord r = mMainStack.isInStackLocked(token);
2733 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 return;
2735 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002736 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002737 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002739 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002740 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002741 if (config != null) {
2742 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002743 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002744 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 }
2746 }
2747 Binder.restoreCallingIdentity(origId);
2748 }
2749 }
2750
2751 public int getRequestedOrientation(IBinder token) {
2752 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002753 ActivityRecord r = mMainStack.isInStackLocked(token);
2754 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2756 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002757 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002758 }
2759 }
2760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002761 /**
2762 * This is the internal entry point for handling Activity.finish().
2763 *
2764 * @param token The Binder token referencing the Activity we want to finish.
2765 * @param resultCode Result code, if any, from this Activity.
2766 * @param resultData Result data (Intent), if any, from this Activity.
2767 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002768 * @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 -08002769 */
2770 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2771 // Refuse possible leaked file descriptors
2772 if (resultData != null && resultData.hasFileDescriptors() == true) {
2773 throw new IllegalArgumentException("File descriptors passed in Intent");
2774 }
2775
2776 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002777 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002779 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002780 if (next != null) {
2781 // ask watcher if this is allowed
2782 boolean resumeOK = true;
2783 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002784 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002785 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002786 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002787 }
2788
2789 if (!resumeOK) {
2790 return false;
2791 }
2792 }
2793 }
2794 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002795 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002796 resultData, "app-request", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002797 Binder.restoreCallingIdentity(origId);
2798 return res;
2799 }
2800 }
2801
Dianne Hackborn860755f2010-06-03 18:47:52 -07002802 public final void finishHeavyWeightApp() {
2803 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2804 != PackageManager.PERMISSION_GRANTED) {
2805 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2806 + Binder.getCallingPid()
2807 + ", uid=" + Binder.getCallingUid()
2808 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2809 Slog.w(TAG, msg);
2810 throw new SecurityException(msg);
2811 }
2812
2813 synchronized(this) {
2814 if (mHeavyWeightProcess == null) {
2815 return;
2816 }
2817
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002818 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002819 mHeavyWeightProcess.activities);
2820 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002821 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002822 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002823 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002824 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002825 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002826 null, "finish-heavy", true);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002827 }
2828 }
2829 }
2830
Dianne Hackborn41203752012-08-31 14:05:51 -07002831 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2832 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -07002833 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07002834 }
2835 }
2836
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002837 public void crashApplication(int uid, int initialPid, String packageName,
2838 String message) {
2839 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2840 != PackageManager.PERMISSION_GRANTED) {
2841 String msg = "Permission Denial: crashApplication() from pid="
2842 + Binder.getCallingPid()
2843 + ", uid=" + Binder.getCallingUid()
2844 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2845 Slog.w(TAG, msg);
2846 throw new SecurityException(msg);
2847 }
2848
2849 synchronized(this) {
2850 ProcessRecord proc = null;
2851
2852 // Figure out which process to kill. We don't trust that initialPid
2853 // still has any relation to current pids, so must scan through the
2854 // list.
2855 synchronized (mPidsSelfLocked) {
2856 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2857 ProcessRecord p = mPidsSelfLocked.valueAt(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002858 if (p.uid != uid) {
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002859 continue;
2860 }
2861 if (p.pid == initialPid) {
2862 proc = p;
2863 break;
2864 }
2865 for (String str : p.pkgList) {
2866 if (str.equals(packageName)) {
2867 proc = p;
2868 }
2869 }
2870 }
2871 }
2872
2873 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002874 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002875 + " initialPid=" + initialPid
2876 + " packageName=" + packageName);
2877 return;
2878 }
2879
2880 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002881 if (proc.pid == Process.myPid()) {
2882 Log.w(TAG, "crashApplication: trying to crash self!");
2883 return;
2884 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002885 long ident = Binder.clearCallingIdentity();
2886 try {
2887 proc.thread.scheduleCrash(message);
2888 } catch (RemoteException e) {
2889 }
2890 Binder.restoreCallingIdentity(ident);
2891 }
2892 }
2893 }
2894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002895 public final void finishSubActivity(IBinder token, String resultWho,
2896 int requestCode) {
2897 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002899 mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002900 Binder.restoreCallingIdentity(origId);
2901 }
2902 }
2903
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002904 public boolean finishActivityAffinity(IBinder token) {
2905 synchronized(this) {
2906 final long origId = Binder.clearCallingIdentity();
2907 boolean res = mMainStack.finishActivityAffinityLocked(token);
2908 Binder.restoreCallingIdentity(origId);
2909 return res;
2910 }
2911 }
2912
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002913 public boolean willActivityBeVisible(IBinder token) {
2914 synchronized(this) {
2915 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002916 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2917 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002918 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002919 return true;
2920 }
2921 if (r.fullscreen && !r.finishing) {
2922 return false;
2923 }
2924 }
2925 return true;
2926 }
2927 }
2928
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002929 public void overridePendingTransition(IBinder token, String packageName,
2930 int enterAnim, int exitAnim) {
2931 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002932 ActivityRecord self = mMainStack.isInStackLocked(token);
2933 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002934 return;
2935 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002936
2937 final long origId = Binder.clearCallingIdentity();
2938
2939 if (self.state == ActivityState.RESUMED
2940 || self.state == ActivityState.PAUSING) {
2941 mWindowManager.overridePendingAppTransition(packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07002942 enterAnim, exitAnim, null);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002943 }
2944
2945 Binder.restoreCallingIdentity(origId);
2946 }
2947 }
2948
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002949 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002950 * Main function for removing an existing process from the activity manager
2951 * as a result of that process going away. Clears out all connections
2952 * to the process.
2953 */
2954 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002955 boolean restarting, boolean allowRestart) {
2956 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002957 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002958 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 }
2960
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002961 if (mProfileProc == app) {
2962 clearProfilerLocked();
2963 }
2964
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 // Just in case...
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002966 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002967 if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
2968 "App died while pausing: " + mMainStack.mPausingActivity);
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002969 mMainStack.mPausingActivity = null;
2970 }
2971 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2972 mMainStack.mLastPausedActivity = null;
2973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974
2975 // Remove this application's activities from active lists.
Dianne Hackborncc5a0552012-10-01 16:32:39 -07002976 boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002977
2978 app.activities.clear();
2979
2980 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002981 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002982 + " running instrumentation " + app.instrumentationClass);
2983 Bundle info = new Bundle();
2984 info.putString("shortMsg", "Process crashed.");
2985 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2986 }
2987
2988 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002989 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002990 // If there was nothing to resume, and we are not already
2991 // restarting this process, but there is a visible activity that
2992 // is hosted by the process... then make sure all visible
2993 // activities are running, taking care of restarting this
2994 // process.
2995 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002996 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002997 }
2998 }
2999 }
3000 }
3001
3002 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
3003 IBinder threadBinder = thread.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003005 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3006 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003007 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
3008 return i;
3009 }
3010 }
3011 return -1;
3012 }
3013
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003014 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003015 IApplicationThread thread) {
3016 if (thread == null) {
3017 return null;
3018 }
3019
3020 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003021 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003022 }
3023
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003024 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003025 IApplicationThread thread) {
3026
3027 mProcDeaths[0]++;
3028
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003029 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3030 synchronized (stats) {
3031 stats.noteProcessDiedLocked(app.info.uid, pid);
3032 }
3033
Magnus Edlund7bb25812010-02-24 15:45:06 +01003034 // Clean up already done if the process has been re-started.
3035 if (app.pid == pid && app.thread != null &&
3036 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07003037 if (!app.killedBackground) {
3038 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
3039 + ") has died.");
3040 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003041 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
Dianne Hackborncc5a0552012-10-01 16:32:39 -07003042 if (DEBUG_CLEANUP) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003043 TAG, "Dying app: " + app + ", pid: " + pid
3044 + ", thread: " + thread.asBinder());
3045 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003046 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003047
3048 if (doLowMem) {
3049 // If there are no longer any background processes running,
3050 // and the app that died was not running instrumentation,
3051 // then tell everyone we are now low on memory.
3052 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003053 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3054 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07003055 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003056 haveBg = true;
3057 break;
3058 }
3059 }
3060
3061 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003062 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003063 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003064 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3065 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07003066 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003067 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
3068 // The low memory report is overriding any current
3069 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003070 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07003071 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003072 rec.lastRequestedGc = 0;
3073 } else {
3074 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003075 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003076 rec.reportLowMemory = true;
3077 rec.lastLowMemory = now;
3078 mProcessesToGc.remove(rec);
3079 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003080 }
3081 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07003082 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003083 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 }
3085 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01003086 } else if (app.pid != pid) {
3087 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003088 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01003089 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003090 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003091 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003092 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 + thread.asBinder());
3094 }
3095 }
3096
Dan Egnor42471dd2010-01-07 17:25:22 -08003097 /**
3098 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07003099 * @param clearTraces causes the dump file to be erased prior to the new
3100 * traces being written, if true; when false, the new traces will be
3101 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003102 * @param firstPids of dalvik VM processes to dump stack traces for first
3103 * @param lastPids of dalvik VM processes to dump stack traces for last
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003104 * @param nativeProcs optional list of native process names to dump stack crawls
Dan Egnor42471dd2010-01-07 17:25:22 -08003105 * @return file containing stack traces, or null if no dump file is configured
3106 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003107 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003108 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003109 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3110 if (tracesPath == null || tracesPath.length() == 0) {
3111 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003112 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003113
3114 File tracesFile = new File(tracesPath);
3115 try {
3116 File tracesDir = tracesFile.getParentFile();
rpcraigec7ed14c2012-07-25 13:10:37 -04003117 if (!tracesDir.exists()) {
3118 tracesFile.mkdirs();
3119 if (!SELinux.restorecon(tracesDir)) {
3120 return null;
3121 }
3122 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003123 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3124
Christopher Tate6ee412d2010-05-28 12:01:56 -07003125 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08003126 tracesFile.createNewFile();
3127 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3128 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003129 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08003130 return null;
3131 }
3132
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003133 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003134 return tracesFile;
3135 }
3136
3137 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003138 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003139 // Use a FileObserver to detect when traces finish writing.
3140 // The order of traces is considered important to maintain for legibility.
3141 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3142 public synchronized void onEvent(int event, String path) { notify(); }
3143 };
3144
3145 try {
3146 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003147
3148 // First collect all of the stacks of the most important pids.
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003149 if (firstPids != null) {
3150 try {
3151 int num = firstPids.size();
3152 for (int i = 0; i < num; i++) {
3153 synchronized (observer) {
3154 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3155 observer.wait(200); // Wait for write-close, give up after 200msec
3156 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003157 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003158 } catch (InterruptedException e) {
3159 Log.wtf(TAG, e);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003160 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003161 }
3162
3163 // Next measure CPU usage.
3164 if (processStats != null) {
3165 processStats.init();
3166 System.gc();
3167 processStats.update();
3168 try {
3169 synchronized (processStats) {
3170 processStats.wait(500); // measure over 1/2 second.
3171 }
3172 } catch (InterruptedException e) {
3173 }
3174 processStats.update();
3175
3176 // We'll take the stack crawls of just the top apps using CPU.
3177 final int N = processStats.countWorkingStats();
3178 int numProcs = 0;
3179 for (int i=0; i<N && numProcs<5; i++) {
3180 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3181 if (lastPids.indexOfKey(stats.pid) >= 0) {
3182 numProcs++;
3183 try {
3184 synchronized (observer) {
3185 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3186 observer.wait(200); // Wait for write-close, give up after 200msec
3187 }
3188 } catch (InterruptedException e) {
3189 Log.wtf(TAG, e);
3190 }
3191
3192 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003193 }
3194 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003195
Dan Egnor42471dd2010-01-07 17:25:22 -08003196 } finally {
3197 observer.stopWatching();
3198 }
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003199
3200 if (nativeProcs != null) {
3201 int[] pids = Process.getPidsForCommands(nativeProcs);
3202 if (pids != null) {
3203 for (int pid : pids) {
3204 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3205 }
3206 }
3207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 }
3209
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003210 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
Dianne Hackborn69dc66e2012-03-26 10:50:54 -07003211 if (true || IS_USER_BUILD) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003212 return;
3213 }
3214 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3215 if (tracesPath == null || tracesPath.length() == 0) {
3216 return;
3217 }
3218
3219 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3220 StrictMode.allowThreadDiskWrites();
3221 try {
3222 final File tracesFile = new File(tracesPath);
3223 final File tracesDir = tracesFile.getParentFile();
3224 final File tracesTmp = new File(tracesDir, "__tmp__");
3225 try {
rpcraigec7ed14c2012-07-25 13:10:37 -04003226 if (!tracesDir.exists()) {
3227 tracesFile.mkdirs();
3228 if (!SELinux.restorecon(tracesDir.getPath())) {
3229 return;
3230 }
3231 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003232 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3233
3234 if (tracesFile.exists()) {
3235 tracesTmp.delete();
3236 tracesFile.renameTo(tracesTmp);
3237 }
3238 StringBuilder sb = new StringBuilder();
3239 Time tobj = new Time();
3240 tobj.set(System.currentTimeMillis());
3241 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3242 sb.append(": ");
3243 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3244 sb.append(" since ");
3245 sb.append(msg);
3246 FileOutputStream fos = new FileOutputStream(tracesFile);
3247 fos.write(sb.toString().getBytes());
3248 if (app == null) {
3249 fos.write("\n*** No application process!".getBytes());
3250 }
3251 fos.close();
3252 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3253 } catch (IOException e) {
3254 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3255 return;
3256 }
3257
3258 if (app != null) {
3259 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3260 firstPids.add(app.pid);
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003261 dumpStackTraces(tracesPath, firstPids, null, null, null);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003262 }
3263
3264 File lastTracesFile = null;
3265 File curTracesFile = null;
3266 for (int i=9; i>=0; i--) {
3267 String name = String.format("slow%02d.txt", i);
3268 curTracesFile = new File(tracesDir, name);
3269 if (curTracesFile.exists()) {
3270 if (lastTracesFile != null) {
3271 curTracesFile.renameTo(lastTracesFile);
3272 } else {
3273 curTracesFile.delete();
3274 }
3275 }
3276 lastTracesFile = curTracesFile;
3277 }
3278 tracesFile.renameTo(curTracesFile);
3279 if (tracesTmp.exists()) {
3280 tracesTmp.renameTo(tracesFile);
3281 }
3282 } finally {
3283 StrictMode.setThreadPolicy(oldPolicy);
3284 }
3285 }
3286
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003287 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07003288 ActivityRecord parent, boolean aboveSystem, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003289 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3290 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3291
Dianne Hackborn287952c2010-09-22 22:34:31 -07003292 if (mController != null) {
3293 try {
3294 // 0 == continue, -1 = kill process immediately
3295 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3296 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3297 } catch (RemoteException e) {
3298 mController = null;
3299 }
3300 }
3301
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003302 long anrTime = SystemClock.uptimeMillis();
3303 if (MONITOR_CPU_USAGE) {
3304 updateCpuStatsNow();
3305 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003306
3307 synchronized (this) {
3308 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3309 if (mShuttingDown) {
3310 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3311 return;
3312 } else if (app.notResponding) {
3313 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3314 return;
3315 } else if (app.crashing) {
3316 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3317 return;
3318 }
3319
3320 // In case we come through here for the same app before completing
3321 // this one, mark as anring now so we will bail out.
3322 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003323
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003324 // Log the ANR to the event log.
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003325 EventLog.writeEvent(EventLogTags.AM_ANR, app.userId, app.pid,
3326 app.processName, app.info.flags, annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003327
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003328 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003329 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003330
3331 int parentPid = app.pid;
3332 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003333 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003334
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003335 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003336
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003337 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3338 ProcessRecord r = mLruProcesses.get(i);
3339 if (r != null && r.thread != null) {
3340 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003341 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3342 if (r.persistent) {
3343 firstPids.add(pid);
3344 } else {
3345 lastPids.put(pid, Boolean.TRUE);
3346 }
3347 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003349 }
3350 }
3351
Dan Egnor42471dd2010-01-07 17:25:22 -08003352 // Log the ANR to the main log.
Jeff Browndeb6ed82012-04-10 14:26:26 -07003353 StringBuilder info = new StringBuilder();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003354 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003355 info.append("ANR in ").append(app.processName);
3356 if (activity != null && activity.shortComponentName != null) {
3357 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003358 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003359 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003360 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003361 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003362 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003363 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003364 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003365 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366
Dianne Hackborn287952c2010-09-22 22:34:31 -07003367 final ProcessStats processStats = new ProcessStats(true);
3368
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003369 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003370
Dan Egnor42471dd2010-01-07 17:25:22 -08003371 String cpuInfo = null;
3372 if (MONITOR_CPU_USAGE) {
3373 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003374 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003375 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003376 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003377 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003378 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 }
3380
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003381 info.append(processStats.printCurrentState(anrTime));
3382
Joe Onorato8a9b2202010-02-26 18:56:32 -08003383 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003384 if (tracesFile == null) {
3385 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3386 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3387 }
3388
Jeff Sharkeya353d262011-10-28 11:12:06 -07003389 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3390 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003391
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003392 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003393 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003394 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3395 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003396 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003397 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3398 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003399 }
3400 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003401 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 }
3403 }
3404
Dan Egnor42471dd2010-01-07 17:25:22 -08003405 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3406 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3407 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003408
3409 synchronized (this) {
3410 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003411 Slog.w(TAG, "Killing " + app + ": background ANR");
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003412 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003413 app.processName, app.setAdj, "background ANR");
3414 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003415 return;
3416 }
3417
3418 // Set the app's notResponding state, and look up the errorReportReceiver
3419 makeAppNotRespondingLocked(app,
3420 activity != null ? activity.shortComponentName : null,
3421 annotation != null ? "ANR " + annotation : "ANR",
3422 info.toString());
3423
3424 // Bring up the infamous App Not Responding dialog
3425 Message msg = Message.obtain();
3426 HashMap map = new HashMap();
3427 msg.what = SHOW_NOT_RESPONDING_MSG;
3428 msg.obj = map;
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07003429 msg.arg1 = aboveSystem ? 1 : 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003430 map.put("app", app);
3431 if (activity != null) {
3432 map.put("activity", activity);
3433 }
3434
3435 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 }
3438
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003439 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3440 if (!mLaunchWarningShown) {
3441 mLaunchWarningShown = true;
3442 mHandler.post(new Runnable() {
3443 @Override
3444 public void run() {
3445 synchronized (ActivityManagerService.this) {
3446 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3447 d.show();
3448 mHandler.postDelayed(new Runnable() {
3449 @Override
3450 public void run() {
3451 synchronized (ActivityManagerService.this) {
3452 d.dismiss();
3453 mLaunchWarningShown = false;
3454 }
3455 }
3456 }, 4000);
3457 }
3458 }
3459 });
3460 }
3461 }
3462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 public boolean clearApplicationUserData(final String packageName,
Dianne Hackborn1676c852012-09-10 14:52:30 -07003464 final IPackageDataObserver observer, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003465 enforceNotIsolatedCaller("clearApplicationUserData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 int uid = Binder.getCallingUid();
3467 int pid = Binder.getCallingPid();
Dianne Hackborn139748f2012-09-24 11:36:57 -07003468 userId = handleIncomingUser(pid, uid,
Dianne Hackborn1676c852012-09-10 14:52:30 -07003469 userId, false, true, "clearApplicationUserData", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 long callingId = Binder.clearCallingIdentity();
3471 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003472 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 int pkgUid = -1;
3474 synchronized(this) {
3475 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003476 pkgUid = pm.getPackageUid(packageName, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003477 } catch (RemoteException e) {
3478 }
3479 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003480 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003481 return false;
3482 }
3483 if (uid == pkgUid || checkComponentPermission(
3484 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003485 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003486 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003487 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003488 } else {
3489 throw new SecurityException(pid+" does not have permission:"+
3490 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3491 "for process:"+packageName);
3492 }
3493 }
3494
3495 try {
3496 //clear application user data
Amith Yamasani483f3b02012-03-13 16:08:00 -07003497 pm.clearApplicationUserData(packageName, observer, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003498 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3499 Uri.fromParts("package", packageName, null));
3500 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003501 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
Amith Yamasani742a6712011-05-04 14:49:28 -07003502 null, null, 0, null, null, null, false, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003503 } catch (RemoteException e) {
3504 }
3505 } finally {
3506 Binder.restoreCallingIdentity(callingId);
3507 }
3508 return true;
3509 }
3510
Dianne Hackborn1676c852012-09-10 14:52:30 -07003511 public void killBackgroundProcesses(final String packageName, int userId) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003512 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3513 != PackageManager.PERMISSION_GRANTED &&
3514 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3515 != PackageManager.PERMISSION_GRANTED) {
3516 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003517 + Binder.getCallingPid()
3518 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003519 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003520 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003521 throw new SecurityException(msg);
3522 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07003523
Dianne Hackborn139748f2012-09-24 11:36:57 -07003524 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackborn1676c852012-09-10 14:52:30 -07003525 userId, true, true, "killBackgroundProcesses", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003526 long callingId = Binder.clearCallingIdentity();
3527 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003528 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003529 synchronized(this) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07003530 int appId = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531 try {
Dianne Hackborn1676c852012-09-10 14:52:30 -07003532 appId = UserHandle.getAppId(pm.getPackageUid(packageName, 0));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003533 } catch (RemoteException e) {
3534 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07003535 if (appId == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003536 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 return;
3538 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07003539 killPackageProcessesLocked(packageName, appId, userId,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003540 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3541 }
3542 } finally {
3543 Binder.restoreCallingIdentity(callingId);
3544 }
3545 }
3546
3547 public void killAllBackgroundProcesses() {
3548 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3549 != PackageManager.PERMISSION_GRANTED) {
3550 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3551 + Binder.getCallingPid()
3552 + ", uid=" + Binder.getCallingUid()
3553 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3554 Slog.w(TAG, msg);
3555 throw new SecurityException(msg);
3556 }
3557
3558 long callingId = Binder.clearCallingIdentity();
3559 try {
3560 synchronized(this) {
3561 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3562 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3563 final int NA = apps.size();
3564 for (int ia=0; ia<NA; ia++) {
3565 ProcessRecord app = apps.valueAt(ia);
3566 if (app.persistent) {
3567 // we don't kill persistent processes
3568 continue;
3569 }
3570 if (app.removed) {
3571 procs.add(app);
3572 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3573 app.removed = true;
3574 procs.add(app);
3575 }
3576 }
3577 }
3578
3579 int N = procs.size();
3580 for (int i=0; i<N; i++) {
3581 removeProcessLocked(procs.get(i), false, true, "kill all background");
3582 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003583 }
3584 } finally {
3585 Binder.restoreCallingIdentity(callingId);
3586 }
3587 }
3588
Dianne Hackborn1676c852012-09-10 14:52:30 -07003589 public void forceStopPackage(final String packageName, int userId) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003590 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3591 != PackageManager.PERMISSION_GRANTED) {
3592 String msg = "Permission Denial: forceStopPackage() from pid="
3593 + Binder.getCallingPid()
3594 + ", uid=" + Binder.getCallingUid()
3595 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003596 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003597 throw new SecurityException(msg);
3598 }
Dianne Hackborn139748f2012-09-24 11:36:57 -07003599 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackborn1676c852012-09-10 14:52:30 -07003600 userId, true, true, "forceStopPackage", null);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003601 long callingId = Binder.clearCallingIdentity();
3602 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003603 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003604 synchronized(this) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07003605 int[] users = userId == UserHandle.USER_ALL
3606 ? getUsersLocked() : new int[] { userId };
3607 for (int user : users) {
3608 int pkgUid = -1;
3609 try {
3610 pkgUid = pm.getPackageUid(packageName, user);
3611 } catch (RemoteException e) {
3612 }
3613 if (pkgUid == -1) {
3614 Slog.w(TAG, "Invalid packageName: " + packageName);
3615 continue;
3616 }
3617 try {
3618 pm.setPackageStoppedState(packageName, true, user);
3619 } catch (RemoteException e) {
3620 } catch (IllegalArgumentException e) {
3621 Slog.w(TAG, "Failed trying to unstop package "
3622 + packageName + ": " + e);
3623 }
Dianne Hackborna8a9bd62012-10-09 15:36:59 -07003624 if (isUserRunningLocked(user, false)) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07003625 forceStopPackageLocked(packageName, pkgUid);
3626 }
Dianne Hackborne7f97212011-02-24 14:40:20 -08003627 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003628 }
3629 } finally {
3630 Binder.restoreCallingIdentity(callingId);
3631 }
3632 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003633
3634 /*
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003635 * The pkg name and app id have to be specified.
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003636 */
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003637 public void killApplicationWithAppId(String pkg, int appid) {
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003638 if (pkg == null) {
3639 return;
3640 }
3641 // Make sure the uid is valid.
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003642 if (appid < 0) {
3643 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003644 return;
3645 }
3646 int callerUid = Binder.getCallingUid();
3647 // Only the system server can kill an application
3648 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003649 // Post an aysnc message to kill the application
3650 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003651 msg.arg1 = appid;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003652 msg.arg2 = 0;
3653 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003654 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003655 } else {
3656 throw new SecurityException(callerUid + " cannot kill pkg: " +
3657 pkg);
3658 }
3659 }
3660
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003661 public void closeSystemDialogs(String reason) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003662 enforceNotIsolatedCaller("closeSystemDialogs");
Dianne Hackborne302a162012-05-15 14:58:32 -07003663
Dianne Hackbornb8839dd2012-09-04 10:55:44 -07003664 final int pid = Binder.getCallingPid();
Dianne Hackborne302a162012-05-15 14:58:32 -07003665 final int uid = Binder.getCallingUid();
3666 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornb8839dd2012-09-04 10:55:44 -07003667 try {
3668 synchronized (this) {
3669 // Only allow this from foreground processes, so that background
3670 // applications can't abuse it to prevent system UI from being shown.
3671 if (uid >= Process.FIRST_APPLICATION_UID) {
3672 ProcessRecord proc;
3673 synchronized (mPidsSelfLocked) {
3674 proc = mPidsSelfLocked.get(pid);
3675 }
3676 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
3677 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
3678 + " from background process " + proc);
3679 return;
3680 }
3681 }
3682 closeSystemDialogsLocked(reason);
3683 }
3684 } finally {
3685 Binder.restoreCallingIdentity(origId);
Dianne Hackborne302a162012-05-15 14:58:32 -07003686 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003687 }
3688
Dianne Hackbornb8839dd2012-09-04 10:55:44 -07003689 void closeSystemDialogsLocked(String reason) {
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003690 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07003691 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3692 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003693 if (reason != null) {
3694 intent.putExtra("reason", reason);
3695 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003696 mWindowManager.closeSystemDialogs(reason);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07003697
Dianne Hackborne302a162012-05-15 14:58:32 -07003698 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3699 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn1927ae82012-06-22 15:21:36 -07003700 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborne302a162012-05-15 14:58:32 -07003701 r.stack.finishActivityLocked(r, i,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07003702 Activity.RESULT_CANCELED, null, "close-sys", true);
Dianne Hackbornffa42482009-09-23 22:20:11 -07003703 }
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003704 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07003705
Dianne Hackbornb8839dd2012-09-04 10:55:44 -07003706 broadcastIntentLocked(null, null, intent, null,
3707 null, 0, null, null, null, false, false, -1,
3708 Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003709 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003710
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003711 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003712 throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003713 enforceNotIsolatedCaller("getProcessMemoryInfo");
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003714 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3715 for (int i=pids.length-1; i>=0; i--) {
3716 infos[i] = new Debug.MemoryInfo();
3717 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003718 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003719 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003720 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003721
Dianne Hackbornb437e092011-08-05 17:50:29 -07003722 public long[] getProcessPss(int[] pids) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003723 enforceNotIsolatedCaller("getProcessPss");
Dianne Hackbornb437e092011-08-05 17:50:29 -07003724 long[] pss = new long[pids.length];
3725 for (int i=pids.length-1; i>=0; i--) {
3726 pss[i] = Debug.getPss(pids[i]);
3727 }
3728 return pss;
3729 }
3730
Christopher Tate5e1ab332009-09-01 20:32:49 -07003731 public void killApplicationProcess(String processName, int uid) {
3732 if (processName == null) {
3733 return;
3734 }
3735
3736 int callerUid = Binder.getCallingUid();
3737 // Only the system server can kill an application
3738 if (callerUid == Process.SYSTEM_UID) {
3739 synchronized (this) {
3740 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003741 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003742 try {
3743 app.thread.scheduleSuicide();
3744 } catch (RemoteException e) {
3745 // If the other end already died, then our work here is done.
3746 }
3747 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003748 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003749 + processName + " / " + uid);
3750 }
3751 }
3752 } else {
3753 throw new SecurityException(callerUid + " cannot kill app process: " +
3754 processName);
3755 }
3756 }
3757
Dianne Hackborn03abb812010-01-04 18:43:19 -08003758 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07003759 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
3760 false, true, false, UserHandle.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003761 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3762 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003763 if (!mProcessesReady) {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07003764 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3765 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003767 intent.putExtra(Intent.EXTRA_UID, uid);
Dianne Hackbornc72fc672012-09-20 13:12:03 -07003768 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003769 broadcastIntentLocked(null, null, intent,
3770 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07003771 false, false,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07003772 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003773 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003774
3775 private void forceStopUserLocked(int userId) {
3776 forceStopPackageLocked(null, -1, false, false, true, false, userId);
3777 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07003778 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
3779 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003780 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3781 broadcastIntentLocked(null, null, intent,
3782 null, null, 0, null, null, null,
3783 false, false,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07003784 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003785 }
3786
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003787 private final boolean killPackageProcessesLocked(String packageName, int appId,
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003788 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3789 boolean doit, boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003790 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003791
Dianne Hackborn03abb812010-01-04 18:43:19 -08003792 // Remove all processes this package may have touched: all with the
3793 // same UID (except for the system or root user), and all whose name
3794 // matches the package name.
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003795 final String procNamePrefix = packageName != null ? (packageName + ":") : null;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003796 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3797 final int NA = apps.size();
3798 for (int ia=0; ia<NA; ia++) {
3799 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003800 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003801 // we don't kill persistent processes
3802 continue;
3803 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003804 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003805 if (doit) {
3806 procs.add(app);
3807 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003808 continue;
3809 }
3810
3811 // Skip process if it doesn't meet our oom adj requirement.
3812 if (app.setAdj < minOomAdj) {
3813 continue;
3814 }
3815
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003816 // If no package is specified, we call all processes under the
3817 // give user id.
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003818 if (packageName == null) {
3819 if (app.userId != userId) {
3820 continue;
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003821 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003822 // Package has been specified, we want to hit all processes
3823 // that match it. We need to qualify this by the processes
3824 // that are running under the specified app and user ID.
3825 } else {
3826 if (UserHandle.getAppId(app.uid) != appId) {
3827 continue;
3828 }
3829 if (userId != UserHandle.USER_ALL && app.userId != userId) {
3830 continue;
3831 }
3832 if (!app.pkgList.contains(packageName)) {
3833 continue;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003834 }
3835 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003836
3837 // Process has passed all conditions, kill it!
3838 if (!doit) {
3839 return true;
3840 }
3841 app.removed = true;
3842 procs.add(app);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003843 }
3844 }
3845
3846 int N = procs.size();
3847 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003848 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003849 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003850 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003851 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003852
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003853 private final boolean forceStopPackageLocked(String name, int appId,
Christopher Tate3dacd842011-08-19 14:56:15 -07003854 boolean callerWillRestart, boolean purgeCache, boolean doit,
Amith Yamasani483f3b02012-03-13 16:08:00 -07003855 boolean evenPersistent, int userId) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003856 int i;
3857 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003859 if (userId == UserHandle.USER_ALL && name == null) {
3860 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
3861 }
3862
3863 if (appId < 0 && name != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003864 try {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003865 appId = UserHandle.getAppId(
3866 AppGlobals.getPackageManager().getPackageUid(name, 0));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003867 } catch (RemoteException e) {
3868 }
3869 }
3870
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003871 if (doit) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003872 if (name != null) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003873 Slog.i(TAG, "Force stopping package " + name + " appid=" + appId
3874 + " user=" + userId);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003875 } else {
3876 Slog.i(TAG, "Force stopping user " + userId);
3877 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003878
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003879 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3880 while (badApps.hasNext()) {
3881 SparseArray<Long> ba = badApps.next();
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003882 for (i=ba.size()-1; i>=0; i--) {
3883 boolean remove = false;
3884 final int entUid = ba.keyAt(i);
3885 if (name != null) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003886 if (userId == UserHandle.USER_ALL) {
3887 if (UserHandle.getAppId(entUid) == appId) {
3888 remove = true;
3889 }
3890 } else {
3891 if (entUid == UserHandle.getUid(userId, appId)) {
3892 remove = true;
3893 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003894 }
3895 } else if (UserHandle.getUserId(entUid) == userId) {
3896 remove = true;
3897 }
3898 if (remove) {
3899 ba.removeAt(i);
3900 }
3901 }
3902 if (ba.size() == 0) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003903 badApps.remove();
3904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003905 }
3906 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003907
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003908 boolean didSomething = killPackageProcessesLocked(name, appId, userId,
3909 -100, callerWillRestart, false, doit, evenPersistent,
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003910 name == null ? ("force stop user " + userId) : ("force stop " + name));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003911
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003912 TaskRecord lastTask = null;
3913 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003914 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003915 final boolean samePackage = r.packageName.equals(name)
3916 || (name == null && r.userId == userId);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003917 if ((userId == UserHandle.USER_ALL || r.userId == userId)
Amith Yamasani13593602012-03-22 16:16:17 -07003918 && (samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003919 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003920 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003921 if (r.finishing) {
3922 // If this activity is just finishing, then it is not
3923 // interesting as far as something to stop.
3924 continue;
3925 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003926 return true;
3927 }
3928 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003929 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003930 if (samePackage) {
3931 if (r.app != null) {
3932 r.app.removed = true;
3933 }
3934 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003935 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003936 lastTask = r.task;
3937 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003938 null, "force-stop", true)) {
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003939 i--;
3940 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003941 }
3942 }
3943
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003944 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3945 if (!doit) {
3946 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003948 didSomething = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003950
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07003951 if (name == null) {
3952 // Remove all sticky broadcasts from this user.
3953 mStickyBroadcasts.remove(userId);
3954 }
3955
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003956 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07003957 if (mProviderMap.collectForceStopProviders(name, appId, doit, evenPersistent,
3958 userId, providers)) {
3959 if (!doit) {
3960 return true;
3961 }
3962 didSomething = true;
3963 }
3964 N = providers.size();
3965 for (i=0; i<N; i++) {
3966 removeDyingProviderLocked(null, providers.get(i), true);
3967 }
3968
Dianne Hackborn861a3b22012-10-12 15:25:20 -07003969 if (name == null) {
3970 // Remove pending intents. For now we only do this when force
3971 // stopping users, because we have some problems when doing this
3972 // for packages -- app widgets are not currently cleaned up for
3973 // such packages, so they can be left with bad pending intents.
3974 if (mIntentSenderRecords.size() > 0) {
3975 Iterator<WeakReference<PendingIntentRecord>> it
3976 = mIntentSenderRecords.values().iterator();
3977 while (it.hasNext()) {
3978 WeakReference<PendingIntentRecord> wpir = it.next();
3979 if (wpir == null) {
3980 it.remove();
3981 continue;
3982 }
3983 PendingIntentRecord pir = wpir.get();
3984 if (pir == null) {
3985 it.remove();
3986 continue;
3987 }
3988 if (name == null) {
3989 // Stopping user, remove all objects for the user.
3990 if (pir.key.userId != userId) {
3991 // Not the same user, skip it.
3992 continue;
3993 }
3994 } else {
3995 if (UserHandle.getAppId(pir.uid) != appId) {
3996 // Different app id, skip it.
3997 continue;
3998 }
3999 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
4000 // Different user, skip it.
4001 continue;
4002 }
4003 if (!pir.key.packageName.equals(name)) {
4004 // Different package, skip it.
4005 continue;
4006 }
4007 }
4008 if (!doit) {
4009 return true;
4010 }
4011 didSomething = true;
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07004012 it.remove();
Dianne Hackborn861a3b22012-10-12 15:25:20 -07004013 pir.canceled = true;
4014 if (pir.key.activity != null) {
4015 pir.key.activity.pendingResults.remove(pir.ref);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07004016 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07004017 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07004018 }
4019 }
4020
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004021 if (doit) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07004022 if (purgeCache && name != null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004023 AttributeCache ac = AttributeCache.instance();
4024 if (ac != null) {
4025 ac.removePackage(name);
4026 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004027 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07004028 if (mBooted) {
4029 mMainStack.resumeTopActivityLocked(null);
4030 mMainStack.scheduleIdleLocked();
4031 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08004032 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004033
4034 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004035 }
4036
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004037 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004038 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 final String name = app.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004040 final int uid = app.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004041 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004042 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004043 + "/" + uid + ")");
4044
4045 mProcessNames.remove(name, uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004046 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004047 if (mHeavyWeightProcess == app) {
Dianne Hackborn41203752012-08-31 14:05:51 -07004048 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4049 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -07004050 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004051 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004052 boolean needRestart = false;
4053 if (app.pid > 0 && app.pid != MY_PID) {
4054 int pid = app.pid;
4055 synchronized (mPidsSelfLocked) {
4056 mPidsSelfLocked.remove(pid);
4057 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4058 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004059 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004060 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004061 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08004062 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004064 if (app.persistent && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004065 if (!callerWillRestart) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004066 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004067 } else {
4068 needRestart = true;
4069 }
4070 }
4071 } else {
4072 mRemovedProcesses.add(app);
4073 }
4074
4075 return needRestart;
4076 }
4077
4078 private final void processStartTimedOutLocked(ProcessRecord app) {
4079 final int pid = app.pid;
4080 boolean gone = false;
4081 synchronized (mPidsSelfLocked) {
4082 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
4083 if (knownApp != null && knownApp.thread == null) {
4084 mPidsSelfLocked.remove(pid);
4085 gone = true;
4086 }
4087 }
4088
4089 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004090 Slog.w(TAG, "Process " + app + " failed to attach");
Dianne Hackbornb12e1352012-09-26 11:39:20 -07004091 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
4092 pid, app.uid, app.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004093 mProcessNames.remove(app.processName, app.uid);
4094 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004095 if (mHeavyWeightProcess == app) {
Dianne Hackborn41203752012-08-31 14:05:51 -07004096 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4097 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -07004098 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07004099 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004100 // Take care of any launching providers waiting for this process.
4101 checkAppInLaunchingProvidersLocked(app, true);
4102 // Take care of any services that are waiting for the process.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07004103 mServices.processStartTimedOutLocked(app);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07004104 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, pid,
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004105 app.processName, app.setAdj, "start timeout");
4106 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07004107 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004108 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07004109 try {
4110 IBackupManager bm = IBackupManager.Stub.asInterface(
4111 ServiceManager.getService(Context.BACKUP_SERVICE));
4112 bm.agentDisconnected(app.info.packageName);
4113 } catch (RemoteException e) {
4114 // Can't happen; the backup manager is local
4115 }
4116 }
Christopher Tatef46723b2012-01-26 14:19:24 -08004117 if (isPendingBroadcastProcessLocked(pid)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004118 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Christopher Tatef46723b2012-01-26 14:19:24 -08004119 skipPendingBroadcastLocked(pid);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08004120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004121 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004122 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004123 }
4124 }
4125
4126 private final boolean attachApplicationLocked(IApplicationThread thread,
4127 int pid) {
4128
4129 // Find the application record that is being attached... either via
4130 // the pid if we are running in multiple processes, or just pull the
4131 // next app record if we are emulating process with anonymous threads.
4132 ProcessRecord app;
4133 if (pid != MY_PID && pid >= 0) {
4134 synchronized (mPidsSelfLocked) {
4135 app = mPidsSelfLocked.get(pid);
4136 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004137 } else {
4138 app = null;
4139 }
4140
4141 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004142 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004143 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08004144 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004145 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07004146 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004147 } else {
4148 try {
4149 thread.scheduleExit();
4150 } catch (Exception e) {
4151 // Ignore exceptions.
4152 }
4153 }
4154 return false;
4155 }
4156
4157 // If this application record is still attached to a previous
4158 // process, clean it up now.
4159 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004160 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004161 }
4162
4163 // Tell the process all about itself.
4164
Joe Onorato8a9b2202010-02-26 18:56:32 -08004165 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 TAG, "Binding process pid " + pid + " to record " + app);
4167
4168 String processName = app.processName;
4169 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004170 AppDeathRecipient adr = new AppDeathRecipient(
4171 app, pid, thread);
4172 thread.asBinder().linkToDeath(adr, 0);
4173 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 } catch (RemoteException e) {
4175 app.resetPackageList();
4176 startProcessLocked(app, "link fail", processName);
4177 return false;
4178 }
4179
Dianne Hackbornb12e1352012-09-26 11:39:20 -07004180 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004181
4182 app.thread = thread;
4183 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08004184 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4185 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004186 app.forcingToForeground = null;
4187 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07004188 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004189 app.debugging = false;
4190
4191 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4192
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004193 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004194 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004195
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004196 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004197 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004198 }
4199
Joe Onorato8a9b2202010-02-26 18:56:32 -08004200 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004201 TAG, "New app record " + app
4202 + " thread=" + thread.asBinder() + " pid=" + pid);
4203 try {
4204 int testMode = IApplicationThread.DEBUG_OFF;
4205 if (mDebugApp != null && mDebugApp.equals(processName)) {
4206 testMode = mWaitForDebugger
4207 ? IApplicationThread.DEBUG_WAIT
4208 : IApplicationThread.DEBUG_ON;
4209 app.debugging = true;
4210 if (mDebugTransient) {
4211 mDebugApp = mOrigDebugApp;
4212 mWaitForDebugger = mOrigWaitForDebugger;
4213 }
4214 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004215 String profileFile = app.instrumentationProfileFile;
4216 ParcelFileDescriptor profileFd = null;
4217 boolean profileAutoStop = false;
4218 if (mProfileApp != null && mProfileApp.equals(processName)) {
4219 mProfileProc = app;
4220 profileFile = mProfileFile;
4221 profileFd = mProfileFd;
4222 profileAutoStop = mAutoStopProfiler;
4223 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08004224 boolean enableOpenGlTrace = false;
4225 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4226 enableOpenGlTrace = true;
4227 mOpenGlTraceApp = null;
4228 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004229
Christopher Tate181fafa2009-05-14 11:12:14 -07004230 // If the app is being launched for restore or full backup, set it up specially
4231 boolean isRestrictedBackupMode = false;
4232 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4233 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07004234 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07004235 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4236 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004237
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07004238 ensurePackageDexOpt(app.instrumentationInfo != null
4239 ? app.instrumentationInfo.packageName
4240 : app.info.packageName);
4241 if (app.instrumentationClass != null) {
4242 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004243 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004244 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07004245 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004246 ApplicationInfo appInfo = app.instrumentationInfo != null
4247 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07004248 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004249 if (profileFd != null) {
4250 profileFd = profileFd.dup();
4251 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004252 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004253 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
Siva Velusamy92a8b222012-03-09 16:24:04 -08004254 app.instrumentationArguments, app.instrumentationWatcher, testMode,
4255 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08004256 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004257 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackbornb12e1352012-09-26 11:39:20 -07004258 updateLruProcessLocked(app, false);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07004259 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004260 } catch (Exception e) {
4261 // todo: Yikes! What should we do? For now we will try to
4262 // start another process, but that could easily get us in
4263 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08004264 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004265
4266 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004267 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 startProcessLocked(app, "bind fail", processName);
4269 return false;
4270 }
4271
4272 // Remove this record from the list of starting applications.
4273 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004274 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4275 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004276 mProcessesOnHold.remove(app);
4277
4278 boolean badApp = false;
4279 boolean didSomething = false;
4280
4281 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004282 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07004283 if (hr != null && normalMode) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004284 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004285 && processName.equals(hr.processName)) {
4286 try {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07004287 if (mHeadless) {
4288 Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4289 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004290 didSomething = true;
4291 }
4292 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004293 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004294 + hr.intent.getComponent().flattenToShortString(), e);
4295 badApp = true;
4296 }
4297 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004298 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 }
4300 }
4301
4302 // Find any services that should be running in this process...
Dianne Hackborn599db5c2012-08-03 19:28:48 -07004303 if (!badApp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 try {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07004305 didSomething |= mServices.attachApplicationLocked(app, processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004306 } catch (Exception e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004307 badApp = true;
4308 }
4309 }
4310
Christopher Tatef46723b2012-01-26 14:19:24 -08004311 // Check if a next-broadcast receiver is in this process...
4312 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 try {
Christopher Tatef46723b2012-01-26 14:19:24 -08004314 didSomething = sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004315 } catch (Exception e) {
Christopher Tatef46723b2012-01-26 14:19:24 -08004316 // If the app died trying to launch the receiver we declare it 'bad'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004317 badApp = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004318 }
4319 }
4320
Christopher Tate181fafa2009-05-14 11:12:14 -07004321 // Check whether the next backup agent is in this process...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004322 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004323 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004324 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07004325 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004326 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4327 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4328 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07004329 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004330 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07004331 e.printStackTrace();
4332 }
4333 }
4334
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004335 if (badApp) {
4336 // todo: Also need to kill application to deal with all
4337 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004338 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004339 return false;
4340 }
4341
4342 if (!didSomething) {
4343 updateOomAdjLocked();
4344 }
4345
4346 return true;
4347 }
4348
4349 public final void attachApplication(IApplicationThread thread) {
4350 synchronized (this) {
4351 int callingPid = Binder.getCallingPid();
4352 final long origId = Binder.clearCallingIdentity();
4353 attachApplicationLocked(thread, callingPid);
4354 Binder.restoreCallingIdentity(origId);
4355 }
4356 }
4357
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004358 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004359 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004360 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4361 if (stopProfiling) {
4362 synchronized (this) {
4363 if (mProfileProc == r.app) {
4364 if (mProfileFd != null) {
4365 try {
4366 mProfileFd.close();
4367 } catch (IOException e) {
4368 }
4369 clearProfilerLocked();
4370 }
4371 }
4372 }
4373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004374 Binder.restoreCallingIdentity(origId);
4375 }
4376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004378 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004379 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 mWindowManager.enableScreenAfterBoot();
Jeff Brownc042ee22012-05-08 13:03:42 -07004381
4382 synchronized (this) {
4383 updateEventDispatchingLocked();
4384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004385 }
4386
Dianne Hackborn661cd522011-08-22 00:26:20 -07004387 public void showBootMessage(final CharSequence msg, final boolean always) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004388 enforceNotIsolatedCaller("showBootMessage");
Dianne Hackborn661cd522011-08-22 00:26:20 -07004389 mWindowManager.showBootMessage(msg, always);
4390 }
4391
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004392 public void dismissKeyguardOnNextActivity() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004393 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
Jeff Sharkey7ffaa982012-04-30 16:59:05 -07004394 final long token = Binder.clearCallingIdentity();
4395 try {
4396 synchronized (this) {
4397 if (mLockScreenShown) {
4398 mLockScreenShown = false;
4399 comeOutOfSleepIfNeededLocked();
4400 }
4401 mMainStack.dismissKeyguardOnNextActivityLocked();
Dianne Hackborn1e88e982012-04-24 18:35:55 -07004402 }
Jeff Sharkey7ffaa982012-04-30 16:59:05 -07004403 } finally {
4404 Binder.restoreCallingIdentity(token);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004405 }
4406 }
4407
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004408 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004409 IntentFilter pkgFilter = new IntentFilter();
4410 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4411 pkgFilter.addDataScheme("package");
4412 mContext.registerReceiver(new BroadcastReceiver() {
4413 @Override
4414 public void onReceive(Context context, Intent intent) {
4415 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4416 if (pkgs != null) {
4417 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004418 synchronized (ActivityManagerService.this) {
Amith Yamasani483f3b02012-03-13 16:08:00 -07004419 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4420 setResultCode(Activity.RESULT_OK);
4421 return;
4422 }
4423 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004424 }
4425 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004426 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004427 }, pkgFilter);
Amith Yamasani13593602012-03-22 16:16:17 -07004428
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004429 synchronized (this) {
4430 // Ensure that any processes we had put on hold are now started
4431 // up.
4432 final int NP = mProcessesOnHold.size();
4433 if (NP > 0) {
4434 ArrayList<ProcessRecord> procs =
4435 new ArrayList<ProcessRecord>(mProcessesOnHold);
4436 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004437 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4438 + procs.get(ip));
4439 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004440 }
4441 }
4442
4443 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004444 // Start looking for apps that are abusing wake locks.
4445 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004446 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004447 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004448 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004449 SystemProperties.set("dev.bootcomplete", "1");
Dianne Hackborn80a4af22012-08-27 19:18:31 -07004450 for (int i=0; i<mStartedUsers.size(); i++) {
4451 UserStartedState uss = mStartedUsers.valueAt(i);
4452 if (uss.mState == UserStartedState.STATE_BOOTING) {
4453 uss.mState = UserStartedState.STATE_RUNNING;
Dianne Hackborn41203752012-08-31 14:05:51 -07004454 final int userId = mStartedUsers.keyAt(i);
4455 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4456 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4457 broadcastIntentLocked(null, null, intent,
Dianne Hackborn80a4af22012-08-27 19:18:31 -07004458 null, null, 0, null, null,
4459 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Dianne Hackborn41203752012-08-31 14:05:51 -07004460 false, false, MY_PID, Process.SYSTEM_UID, userId);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07004461 }
Amith Yamasani4860cfc2012-08-08 19:14:18 -07004462 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004463 }
4464 }
4465 }
4466
4467 final void ensureBootCompleted() {
4468 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004469 boolean enableScreen;
4470 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004471 booting = mBooting;
4472 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004473 enableScreen = !mBooted;
4474 mBooted = true;
4475 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004476
4477 if (booting) {
4478 finishBooting();
4479 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004480
4481 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004482 enableScreenAfterBoot();
4483 }
4484 }
Dianne Hackbornad9b32112012-09-17 15:35:01 -07004485
4486 public final void activityResumed(IBinder token) {
4487 final long origId = Binder.clearCallingIdentity();
4488 mMainStack.activityResumed(token);
4489 Binder.restoreCallingIdentity(origId);
4490 }
4491
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004492 public final void activityPaused(IBinder token) {
4493 final long origId = Binder.clearCallingIdentity();
4494 mMainStack.activityPaused(token, false);
4495 Binder.restoreCallingIdentity(origId);
4496 }
4497
4498 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4499 CharSequence description) {
4500 if (localLOGV) Slog.v(
4501 TAG, "Activity stopped: token=" + token);
4502
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 // Refuse possible leaked file descriptors
4504 if (icicle != null && icicle.hasFileDescriptors()) {
4505 throw new IllegalArgumentException("File descriptors passed in Bundle");
4506 }
4507
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004508 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509
4510 final long origId = Binder.clearCallingIdentity();
4511
4512 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004513 r = mMainStack.isInStackLocked(token);
4514 if (r != null) {
4515 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004516 }
4517 }
4518
4519 if (r != null) {
4520 sendPendingThumbnail(r, null, null, null, false);
4521 }
4522
4523 trimApplications();
4524
4525 Binder.restoreCallingIdentity(origId);
4526 }
4527
4528 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004529 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004530 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004531 }
4532
4533 public String getCallingPackage(IBinder token) {
4534 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004535 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004536 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004537 }
4538 }
4539
4540 public ComponentName getCallingActivity(IBinder token) {
4541 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004542 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004543 return r != null ? r.intent.getComponent() : null;
4544 }
4545 }
4546
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004547 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004548 ActivityRecord r = mMainStack.isInStackLocked(token);
4549 if (r == null) {
4550 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004551 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004552 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004553 }
4554
4555 public ComponentName getActivityClassForToken(IBinder token) {
4556 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004557 ActivityRecord r = mMainStack.isInStackLocked(token);
4558 if (r == null) {
4559 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004560 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004561 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004562 }
4563 }
4564
4565 public String getPackageForToken(IBinder token) {
4566 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004567 ActivityRecord r = mMainStack.isInStackLocked(token);
4568 if (r == null) {
4569 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004570 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004571 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004572 }
4573 }
4574
4575 public IIntentSender getIntentSender(int type,
4576 String packageName, IBinder token, String resultWho,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004577 int requestCode, Intent[] intents, String[] resolvedTypes,
Dianne Hackborn41203752012-08-31 14:05:51 -07004578 int flags, Bundle options, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004579 enforceNotIsolatedCaller("getIntentSender");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004580 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004581 if (intents != null) {
4582 if (intents.length < 1) {
4583 throw new IllegalArgumentException("Intents array length must be >= 1");
4584 }
4585 for (int i=0; i<intents.length; i++) {
4586 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004587 if (intent != null) {
4588 if (intent.hasFileDescriptors()) {
4589 throw new IllegalArgumentException("File descriptors passed in Intent");
4590 }
Dianne Hackborna4972e92012-03-14 10:38:05 -07004591 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004592 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4593 throw new IllegalArgumentException(
4594 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4595 }
4596 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004597 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004598 }
4599 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004600 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004601 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004602 }
4603 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004604 if (options != null) {
4605 if (options.hasFileDescriptors()) {
4606 throw new IllegalArgumentException("File descriptors passed in options");
4607 }
4608 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004609
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004610 synchronized(this) {
4611 int callingUid = Binder.getCallingUid();
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -07004612 int origUserId = userId;
Dianne Hackborn139748f2012-09-24 11:36:57 -07004613 userId = handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
Amith Yamasani2c7ebea2012-10-30 15:28:27 -07004614 type == ActivityManager.INTENT_SENDER_BROADCAST, false,
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -07004615 "getIntentSender", null);
4616 if (origUserId == UserHandle.USER_CURRENT) {
4617 // We don't want to evaluate this until the pending intent is
4618 // actually executed. However, we do want to always do the
4619 // security checking for it above.
4620 userId = UserHandle.USER_CURRENT;
4621 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004622 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004623 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004624 int uid = AppGlobals.getPackageManager()
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004625 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4626 if (!UserHandle.isSameApp(callingUid, uid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004627 String msg = "Permission Denial: getIntentSender() from pid="
4628 + Binder.getCallingPid()
4629 + ", uid=" + Binder.getCallingUid()
4630 + ", (need uid=" + uid + ")"
4631 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004632 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004633 throw new SecurityException(msg);
4634 }
4635 }
Dianne Hackborn41203752012-08-31 14:05:51 -07004636
4637 return getIntentSenderLocked(type, packageName, callingUid, userId,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004638 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004640 } catch (RemoteException e) {
4641 throw new SecurityException(e);
4642 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004643 }
4644 }
4645
Dianne Hackborn41203752012-08-31 14:05:51 -07004646 IIntentSender getIntentSenderLocked(int type, String packageName,
4647 int callingUid, int userId, IBinder token, String resultWho,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004648 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4649 Bundle options) {
Amith Yamasani742a6712011-05-04 14:49:28 -07004650 if (DEBUG_MU)
4651 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004652 ActivityRecord activity = null;
Dianne Hackborna4972e92012-03-14 10:38:05 -07004653 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004654 activity = mMainStack.isInStackLocked(token);
4655 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004656 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004657 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004658 if (activity.finishing) {
4659 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004660 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004661 }
4662
4663 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4664 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4665 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4666 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4667 |PendingIntent.FLAG_UPDATE_CURRENT);
4668
4669 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4670 type, packageName, activity, resultWho,
Dianne Hackborn41203752012-08-31 14:05:51 -07004671 requestCode, intents, resolvedTypes, flags, options, userId);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004672 WeakReference<PendingIntentRecord> ref;
4673 ref = mIntentSenderRecords.get(key);
4674 PendingIntentRecord rec = ref != null ? ref.get() : null;
4675 if (rec != null) {
4676 if (!cancelCurrent) {
4677 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004678 if (rec.key.requestIntent != null) {
Adam Powell501d4a52012-04-30 15:03:57 -07004679 rec.key.requestIntent.replaceExtras(intents != null ?
4680 intents[intents.length - 1] : null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004681 }
4682 if (intents != null) {
4683 intents[intents.length-1] = rec.key.requestIntent;
4684 rec.key.allIntents = intents;
4685 rec.key.allResolvedTypes = resolvedTypes;
4686 } else {
4687 rec.key.allIntents = null;
4688 rec.key.allResolvedTypes = null;
4689 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004690 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004691 return rec;
4692 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004693 rec.canceled = true;
4694 mIntentSenderRecords.remove(key);
4695 }
4696 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004697 return rec;
4698 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004699 rec = new PendingIntentRecord(this, key, callingUid);
4700 mIntentSenderRecords.put(key, rec.ref);
Dianne Hackborna4972e92012-03-14 10:38:05 -07004701 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004702 if (activity.pendingResults == null) {
4703 activity.pendingResults
4704 = new HashSet<WeakReference<PendingIntentRecord>>();
4705 }
4706 activity.pendingResults.add(rec.ref);
4707 }
4708 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004709 }
4710
4711 public void cancelIntentSender(IIntentSender sender) {
4712 if (!(sender instanceof PendingIntentRecord)) {
4713 return;
4714 }
4715 synchronized(this) {
4716 PendingIntentRecord rec = (PendingIntentRecord)sender;
4717 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004718 int uid = AppGlobals.getPackageManager()
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004719 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4720 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004721 String msg = "Permission Denial: cancelIntentSender() from pid="
4722 + Binder.getCallingPid()
4723 + ", uid=" + Binder.getCallingUid()
4724 + " is not allowed to cancel packges "
4725 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004726 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004727 throw new SecurityException(msg);
4728 }
4729 } catch (RemoteException e) {
4730 throw new SecurityException(e);
4731 }
4732 cancelIntentSenderLocked(rec, true);
4733 }
4734 }
4735
4736 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4737 rec.canceled = true;
4738 mIntentSenderRecords.remove(rec.key);
4739 if (cleanActivity && rec.key.activity != null) {
4740 rec.key.activity.pendingResults.remove(rec.ref);
4741 }
4742 }
4743
4744 public String getPackageForIntentSender(IIntentSender pendingResult) {
4745 if (!(pendingResult instanceof PendingIntentRecord)) {
4746 return null;
4747 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004748 try {
4749 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4750 return res.key.packageName;
4751 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004752 }
4753 return null;
4754 }
4755
Christopher Tatec4a07d12012-04-06 14:19:13 -07004756 public int getUidForIntentSender(IIntentSender sender) {
4757 if (sender instanceof PendingIntentRecord) {
4758 try {
4759 PendingIntentRecord res = (PendingIntentRecord)sender;
4760 return res.uid;
4761 } catch (ClassCastException e) {
4762 }
4763 }
4764 return -1;
4765 }
4766
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004767 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4768 if (!(pendingResult instanceof PendingIntentRecord)) {
4769 return false;
4770 }
4771 try {
4772 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4773 if (res.key.allIntents == null) {
4774 return false;
4775 }
4776 for (int i=0; i<res.key.allIntents.length; i++) {
4777 Intent intent = res.key.allIntents[i];
4778 if (intent.getPackage() != null && intent.getComponent() != null) {
4779 return false;
4780 }
4781 }
4782 return true;
4783 } catch (ClassCastException e) {
4784 }
4785 return false;
4786 }
4787
Dianne Hackborn1927ae82012-06-22 15:21:36 -07004788 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4789 if (!(pendingResult instanceof PendingIntentRecord)) {
4790 return false;
4791 }
4792 try {
4793 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4794 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4795 return true;
4796 }
4797 return false;
4798 } catch (ClassCastException e) {
4799 }
4800 return false;
4801 }
4802
Dianne Hackborn81038902012-11-26 17:04:09 -08004803 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
4804 if (!(pendingResult instanceof PendingIntentRecord)) {
4805 return null;
4806 }
4807 try {
4808 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4809 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
4810 } catch (ClassCastException e) {
4811 }
4812 return null;
4813 }
4814
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004815 public void setProcessLimit(int max) {
4816 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4817 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004818 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004819 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004820 mProcessLimitOverride = max;
4821 }
4822 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004823 }
4824
4825 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004826 synchronized (this) {
4827 return mProcessLimitOverride;
4828 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004829 }
4830
4831 void foregroundTokenDied(ForegroundToken token) {
4832 synchronized (ActivityManagerService.this) {
4833 synchronized (mPidsSelfLocked) {
4834 ForegroundToken cur
4835 = mForegroundProcesses.get(token.pid);
4836 if (cur != token) {
4837 return;
4838 }
4839 mForegroundProcesses.remove(token.pid);
4840 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4841 if (pr == null) {
4842 return;
4843 }
4844 pr.forcingToForeground = null;
4845 pr.foregroundServices = false;
4846 }
4847 updateOomAdjLocked();
4848 }
4849 }
4850
4851 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4852 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4853 "setProcessForeground()");
4854 synchronized(this) {
4855 boolean changed = false;
4856
4857 synchronized (mPidsSelfLocked) {
4858 ProcessRecord pr = mPidsSelfLocked.get(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004859 if (pr == null && isForeground) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004860 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004861 return;
4862 }
4863 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4864 if (oldToken != null) {
4865 oldToken.token.unlinkToDeath(oldToken, 0);
4866 mForegroundProcesses.remove(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004867 if (pr != null) {
4868 pr.forcingToForeground = null;
4869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004870 changed = true;
4871 }
4872 if (isForeground && token != null) {
4873 ForegroundToken newToken = new ForegroundToken() {
4874 public void binderDied() {
4875 foregroundTokenDied(this);
4876 }
4877 };
4878 newToken.pid = pid;
4879 newToken.token = token;
4880 try {
4881 token.linkToDeath(newToken, 0);
4882 mForegroundProcesses.put(pid, newToken);
4883 pr.forcingToForeground = token;
4884 changed = true;
4885 } catch (RemoteException e) {
4886 // If the process died while doing this, we will later
4887 // do the cleanup with the process death link.
4888 }
4889 }
4890 }
4891
4892 if (changed) {
4893 updateOomAdjLocked();
4894 }
4895 }
4896 }
4897
4898 // =========================================================
4899 // PERMISSIONS
4900 // =========================================================
4901
4902 static class PermissionController extends IPermissionController.Stub {
4903 ActivityManagerService mActivityManagerService;
4904 PermissionController(ActivityManagerService activityManagerService) {
4905 mActivityManagerService = activityManagerService;
4906 }
4907
4908 public boolean checkPermission(String permission, int pid, int uid) {
4909 return mActivityManagerService.checkPermission(permission, pid,
4910 uid) == PackageManager.PERMISSION_GRANTED;
4911 }
4912 }
4913
4914 /**
4915 * This can be called with or without the global lock held.
4916 */
4917 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004918 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 // We might be performing an operation on behalf of an indirect binder
4920 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4921 // client identity accordingly before proceeding.
4922 Identity tlsIdentity = sCallerIdentity.get();
4923 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004924 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004925 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4926 uid = tlsIdentity.uid;
4927 pid = tlsIdentity.pid;
4928 }
4929
Dianne Hackborn5320eb82012-05-18 12:05:04 -07004930 if (pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004931 return PackageManager.PERMISSION_GRANTED;
4932 }
Dianne Hackborn5320eb82012-05-18 12:05:04 -07004933
4934 return ActivityManager.checkComponentPermission(permission, uid,
4935 owningUid, exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004936 }
4937
4938 /**
4939 * As the only public entry point for permissions checking, this method
4940 * can enforce the semantic that requesting a check on a null global
4941 * permission is automatically denied. (Internally a null permission
4942 * string is used when calling {@link #checkComponentPermission} in cases
4943 * when only uid-based security is needed.)
4944 *
4945 * This can be called with or without the global lock held.
4946 */
4947 public int checkPermission(String permission, int pid, int uid) {
4948 if (permission == null) {
4949 return PackageManager.PERMISSION_DENIED;
4950 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004951 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 }
4953
4954 /**
4955 * Binder IPC calls go through the public entry point.
4956 * This can be called with or without the global lock held.
4957 */
4958 int checkCallingPermission(String permission) {
4959 return checkPermission(permission,
4960 Binder.getCallingPid(),
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004961 UserHandle.getAppId(Binder.getCallingUid()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 }
4963
4964 /**
4965 * This can be called with or without the global lock held.
4966 */
4967 void enforceCallingPermission(String permission, String func) {
4968 if (checkCallingPermission(permission)
4969 == PackageManager.PERMISSION_GRANTED) {
4970 return;
4971 }
4972
4973 String msg = "Permission Denial: " + func + " from pid="
4974 + Binder.getCallingPid()
4975 + ", uid=" + Binder.getCallingUid()
4976 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004977 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004978 throw new SecurityException(msg);
4979 }
4980
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004981 /**
4982 * Determine if UID is holding permissions required to access {@link Uri} in
4983 * the given {@link ProviderInfo}. Final permission checking is always done
4984 * in {@link ContentProvider}.
4985 */
4986 private final boolean checkHoldingPermissionsLocked(
4987 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004988 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4989 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004990
4991 if (pi.applicationInfo.uid == uid) {
4992 return true;
4993 } else if (!pi.exported) {
4994 return false;
4995 }
4996
4997 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4998 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004999 try {
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005000 // check if target holds top-level <provider> permissions
5001 if (!readMet && pi.readPermission != null
5002 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
5003 readMet = true;
5004 }
5005 if (!writeMet && pi.writePermission != null
5006 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
5007 writeMet = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005008 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005009
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005010 // track if unprotected read/write is allowed; any denied
5011 // <path-permission> below removes this ability
5012 boolean allowDefaultRead = pi.readPermission == null;
5013 boolean allowDefaultWrite = pi.writePermission == null;
Dianne Hackborn48058e82010-09-27 16:53:23 -07005014
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005015 // check if target holds any <path-permission> that match uri
5016 final PathPermission[] pps = pi.pathPermissions;
5017 if (pps != null) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07005018 final String path = uri.getPath();
5019 int i = pps.length;
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005020 while (i > 0 && (!readMet || !writeMet)) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07005021 i--;
5022 PathPermission pp = pps[i];
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005023 if (pp.match(path)) {
5024 if (!readMet) {
5025 final String pprperm = pp.getReadPermission();
5026 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
5027 + pprperm + " for " + pp.getPath()
5028 + ": match=" + pp.match(path)
5029 + " check=" + pm.checkUidPermission(pprperm, uid));
5030 if (pprperm != null) {
5031 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
5032 readMet = true;
5033 } else {
5034 allowDefaultRead = false;
5035 }
5036 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005037 }
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005038 if (!writeMet) {
5039 final String ppwperm = pp.getWritePermission();
5040 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
5041 + ppwperm + " for " + pp.getPath()
5042 + ": match=" + pp.match(path)
5043 + " check=" + pm.checkUidPermission(ppwperm, uid));
5044 if (ppwperm != null) {
5045 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
5046 writeMet = true;
5047 } else {
5048 allowDefaultWrite = false;
5049 }
5050 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005051 }
5052 }
5053 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005054 }
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005055
5056 // grant unprotected <provider> read/write, if not blocked by
5057 // <path-permission> above
5058 if (allowDefaultRead) readMet = true;
5059 if (allowDefaultWrite) writeMet = true;
5060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005061 } catch (RemoteException e) {
5062 return false;
5063 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07005064
Jeff Sharkey110a6b62012-03-12 11:12:41 -07005065 return readMet && writeMet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005066 }
5067
5068 private final boolean checkUriPermissionLocked(Uri uri, int uid,
5069 int modeFlags) {
5070 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07005071 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005072 return true;
5073 }
5074 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
5075 if (perms == null) return false;
5076 UriPermission perm = perms.get(uri);
5077 if (perm == null) return false;
5078 return (modeFlags&perm.modeFlags) == modeFlags;
5079 }
5080
5081 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005082 enforceNotIsolatedCaller("checkUriPermission");
5083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005084 // Another redirected-binder-call permissions check as in
5085 // {@link checkComponentPermission}.
5086 Identity tlsIdentity = sCallerIdentity.get();
5087 if (tlsIdentity != null) {
5088 uid = tlsIdentity.uid;
5089 pid = tlsIdentity.pid;
5090 }
5091
5092 // Our own process gets to do everything.
5093 if (pid == MY_PID) {
5094 return PackageManager.PERMISSION_GRANTED;
5095 }
5096 synchronized(this) {
5097 return checkUriPermissionLocked(uri, uid, modeFlags)
5098 ? PackageManager.PERMISSION_GRANTED
5099 : PackageManager.PERMISSION_DENIED;
5100 }
5101 }
5102
Dianne Hackborn39792d22010-08-19 18:01:52 -07005103 /**
5104 * Check if the targetPkg can be granted permission to access uri by
5105 * the callingUid using the given modeFlags. Throws a security exception
5106 * if callingUid is not allowed to do this. Returns the uid of the target
5107 * if the URI permission grant should be performed; returns -1 if it is not
5108 * needed (for example targetPkg already has permission to access the URI).
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005109 * If you already know the uid of the target, you can supply it in
5110 * lastTargetUid else set that to -1.
Dianne Hackborn39792d22010-08-19 18:01:52 -07005111 */
5112 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005113 Uri uri, int modeFlags, int lastTargetUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005114 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5115 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5116 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005117 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005118 }
5119
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005120 if (targetPkg != null) {
5121 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5122 "Checking grant " + targetPkg + " permission to " + uri);
5123 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005124
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005125 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126
5127 // If this is not a content: uri, we can't do anything with it.
5128 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005129 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005130 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005131 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005132 }
5133
5134 String name = uri.getAuthority();
5135 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07005136 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07005137 UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005138 if (cpr != null) {
5139 pi = cpr.info;
5140 } else {
5141 try {
5142 pi = pm.resolveContentProvider(name,
Dianne Hackborn11f0cb72012-09-16 17:12:34 -07005143 PackageManager.GET_URI_PERMISSION_PATTERNS,
5144 UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005145 } catch (RemoteException ex) {
5146 }
5147 }
5148 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005149 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07005150 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005151 }
5152
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005153 int targetUid = lastTargetUid;
5154 if (targetUid < 0 && targetPkg != null) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005155 try {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07005156 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005157 if (targetUid < 0) {
5158 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5159 "Can't grant URI permission no uid for: " + targetPkg);
5160 return -1;
5161 }
5162 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07005163 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005165 }
5166
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005167 if (targetUid >= 0) {
5168 // First... does the target actually need this permission?
5169 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
5170 // No need to grant the target this permission.
5171 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
5172 "Target " + targetPkg + " already has full permission to " + uri);
5173 return -1;
5174 }
5175 } else {
5176 // First... there is no target package, so can anyone access it?
5177 boolean allowed = pi.exported;
5178 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5179 if (pi.readPermission != null) {
5180 allowed = false;
5181 }
5182 }
5183 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5184 if (pi.writePermission != null) {
5185 allowed = false;
5186 }
5187 }
5188 if (allowed) {
5189 return -1;
5190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005191 }
5192
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005193 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005194 if (!pi.grantUriPermissions) {
5195 throw new SecurityException("Provider " + pi.packageName
5196 + "/" + pi.name
5197 + " does not allow granting of Uri permissions (uri "
5198 + uri + ")");
5199 }
5200 if (pi.uriPermissionPatterns != null) {
5201 final int N = pi.uriPermissionPatterns.length;
5202 boolean allowed = false;
5203 for (int i=0; i<N; i++) {
5204 if (pi.uriPermissionPatterns[i] != null
5205 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5206 allowed = true;
5207 break;
5208 }
5209 }
5210 if (!allowed) {
5211 throw new SecurityException("Provider " + pi.packageName
5212 + "/" + pi.name
5213 + " does not allow granting of permission to path of Uri "
5214 + uri);
5215 }
5216 }
5217
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005218 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005219 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005220 if (callingUid != Process.myUid()) {
5221 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5222 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5223 throw new SecurityException("Uid " + callingUid
5224 + " does not have permission to uri " + uri);
5225 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005226 }
5227 }
5228
Dianne Hackborn39792d22010-08-19 18:01:52 -07005229 return targetUid;
5230 }
5231
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005232 public int checkGrantUriPermission(int callingUid, String targetPkg,
5233 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005234 enforceNotIsolatedCaller("checkGrantUriPermission");
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005235 synchronized(this) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005236 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005237 }
5238 }
5239
Dianne Hackborn39792d22010-08-19 18:01:52 -07005240 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5241 Uri uri, int modeFlags, UriPermissionOwner owner) {
5242 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5243 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5244 if (modeFlags == 0) {
5245 return;
5246 }
5247
5248 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005249 // to the uri, and the target doesn't. Let's now give this to
5250 // the target.
5251
Joe Onorato8a9b2202010-02-26 18:56:32 -08005252 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005253 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005254
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005255 HashMap<Uri, UriPermission> targetUris
5256 = mGrantedUriPermissions.get(targetUid);
5257 if (targetUris == null) {
5258 targetUris = new HashMap<Uri, UriPermission>();
5259 mGrantedUriPermissions.put(targetUid, targetUris);
5260 }
5261
5262 UriPermission perm = targetUris.get(uri);
5263 if (perm == null) {
5264 perm = new UriPermission(targetUid, uri);
5265 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005267
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005268 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005269 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005270 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08005271 } else {
5272 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5273 perm.readOwners.add(owner);
5274 owner.addReadPermission(perm);
5275 }
5276 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5277 perm.writeOwners.add(owner);
5278 owner.addWritePermission(perm);
5279 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005280 }
5281 }
5282
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005283 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5284 int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005285 if (targetPkg == null) {
5286 throw new NullPointerException("targetPkg");
5287 }
5288
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005289 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005290 if (targetUid < 0) {
5291 return;
5292 }
5293
5294 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5295 }
5296
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005297 static class NeededUriGrants extends ArrayList<Uri> {
5298 final String targetPkg;
5299 final int targetUid;
5300 final int flags;
5301
5302 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5303 targetPkg = _targetPkg;
5304 targetUid = _targetUid;
5305 flags = _flags;
5306 }
5307 }
5308
Dianne Hackborn39792d22010-08-19 18:01:52 -07005309 /**
5310 * Like checkGrantUriPermissionLocked, but takes an Intent.
5311 */
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005312 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5313 String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07005314 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005315 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5316 + " clip=" + (intent != null ? intent.getClipData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005317 + " from " + intent + "; flags=0x"
5318 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5319
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005320 if (targetPkg == null) {
5321 throw new NullPointerException("targetPkg");
5322 }
5323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005324 if (intent == null) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005325 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005326 }
5327 Uri data = intent.getData();
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005328 ClipData clip = intent.getClipData();
5329 if (data == null && clip == null) {
5330 return null;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005331 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005332 if (data != null) {
5333 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5334 mode, needed != null ? needed.targetUid : -1);
5335 if (target > 0) {
5336 if (needed == null) {
5337 needed = new NeededUriGrants(targetPkg, target, mode);
5338 }
5339 needed.add(data);
5340 }
5341 }
5342 if (clip != null) {
5343 for (int i=0; i<clip.getItemCount(); i++) {
5344 Uri uri = clip.getItemAt(i).getUri();
5345 if (uri != null) {
5346 int target = -1;
5347 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5348 mode, needed != null ? needed.targetUid : -1);
5349 if (target > 0) {
5350 if (needed == null) {
5351 needed = new NeededUriGrants(targetPkg, target, mode);
5352 }
5353 needed.add(uri);
5354 }
5355 } else {
5356 Intent clipIntent = clip.getItemAt(i).getIntent();
5357 if (clipIntent != null) {
5358 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5359 callingUid, targetPkg, clipIntent, mode, needed);
5360 if (newNeeded != null) {
5361 needed = newNeeded;
5362 }
5363 }
5364 }
5365 }
5366 }
5367
5368 return needed;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005369 }
5370
5371 /**
5372 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5373 */
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005374 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5375 UriPermissionOwner owner) {
5376 if (needed != null) {
5377 for (int i=0; i<needed.size(); i++) {
5378 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5379 needed.get(i), needed.flags, owner);
5380 }
5381 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005382 }
5383
5384 void grantUriPermissionFromIntentLocked(int callingUid,
5385 String targetPkg, Intent intent, UriPermissionOwner owner) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005386 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
Dianne Hackbornd9781fe2012-03-08 18:04:18 -08005387 intent, intent != null ? intent.getFlags() : 0, null);
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005388 if (needed == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005389 return;
5390 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005391
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005392 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005393 }
5394
5395 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5396 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005397 enforceNotIsolatedCaller("grantUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005398 synchronized(this) {
5399 final ProcessRecord r = getRecordForAppLocked(caller);
5400 if (r == null) {
5401 throw new SecurityException("Unable to find app for caller "
5402 + caller
5403 + " when granting permission to uri " + uri);
5404 }
5405 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005406 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005407 }
5408 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005409 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005410 }
5411
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005412 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005413 null);
5414 }
5415 }
5416
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005417 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005418 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5419 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5420 HashMap<Uri, UriPermission> perms
5421 = mGrantedUriPermissions.get(perm.uid);
5422 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005423 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005424 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005425 perms.remove(perm.uri);
5426 if (perms.size() == 0) {
5427 mGrantedUriPermissions.remove(perm.uid);
5428 }
5429 }
5430 }
5431 }
5432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005433 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5434 int modeFlags) {
5435 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5436 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5437 if (modeFlags == 0) {
5438 return;
5439 }
5440
Joe Onorato8a9b2202010-02-26 18:56:32 -08005441 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005442 "Revoking all granted permissions to " + uri);
5443
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005444 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005445
5446 final String authority = uri.getAuthority();
5447 ProviderInfo pi = null;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07005448 int userId = UserHandle.getUserId(callingUid);
Amith Yamasani483f3b02012-03-13 16:08:00 -07005449 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005450 if (cpr != null) {
5451 pi = cpr.info;
5452 } else {
5453 try {
5454 pi = pm.resolveContentProvider(authority,
Amith Yamasani483f3b02012-03-13 16:08:00 -07005455 PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456 } catch (RemoteException ex) {
5457 }
5458 }
5459 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005460 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005461 return;
5462 }
5463
5464 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07005465 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005466 // Right now, if you are not the original owner of the permission,
5467 // you are not allowed to revoke it.
5468 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5469 throw new SecurityException("Uid " + callingUid
5470 + " does not have permission to uri " + uri);
5471 //}
5472 }
5473
5474 // Go through all of the permissions and remove any that match.
5475 final List<String> SEGMENTS = uri.getPathSegments();
5476 if (SEGMENTS != null) {
5477 final int NS = SEGMENTS.size();
5478 int N = mGrantedUriPermissions.size();
5479 for (int i=0; i<N; i++) {
5480 HashMap<Uri, UriPermission> perms
5481 = mGrantedUriPermissions.valueAt(i);
5482 Iterator<UriPermission> it = perms.values().iterator();
5483 toploop:
5484 while (it.hasNext()) {
5485 UriPermission perm = it.next();
5486 Uri targetUri = perm.uri;
5487 if (!authority.equals(targetUri.getAuthority())) {
5488 continue;
5489 }
5490 List<String> targetSegments = targetUri.getPathSegments();
5491 if (targetSegments == null) {
5492 continue;
5493 }
5494 if (targetSegments.size() < NS) {
5495 continue;
5496 }
5497 for (int j=0; j<NS; j++) {
5498 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5499 continue toploop;
5500 }
5501 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005502 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005503 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005504 perm.clearModes(modeFlags);
5505 if (perm.modeFlags == 0) {
5506 it.remove();
5507 }
5508 }
5509 if (perms.size() == 0) {
5510 mGrantedUriPermissions.remove(
5511 mGrantedUriPermissions.keyAt(i));
5512 N--;
5513 i--;
5514 }
5515 }
5516 }
5517 }
5518
5519 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5520 int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005521 enforceNotIsolatedCaller("revokeUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522 synchronized(this) {
5523 final ProcessRecord r = getRecordForAppLocked(caller);
5524 if (r == null) {
5525 throw new SecurityException("Unable to find app for caller "
5526 + caller
5527 + " when revoking permission to uri " + uri);
5528 }
5529 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005530 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005531 return;
5532 }
5533
5534 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5535 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5536 if (modeFlags == 0) {
5537 return;
5538 }
5539
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005540 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005541
5542 final String authority = uri.getAuthority();
5543 ProviderInfo pi = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005544 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005545 if (cpr != null) {
5546 pi = cpr.info;
5547 } else {
5548 try {
5549 pi = pm.resolveContentProvider(authority,
Amith Yamasani483f3b02012-03-13 16:08:00 -07005550 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005551 } catch (RemoteException ex) {
5552 }
5553 }
5554 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005555 Slog.w(TAG, "No content provider found for permission revoke: "
5556 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005557 return;
5558 }
5559
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005560 revokeUriPermissionLocked(r.uid, uri, modeFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005561 }
5562 }
5563
Dianne Hackborn7e269642010-08-25 19:50:20 -07005564 @Override
5565 public IBinder newUriPermissionOwner(String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005566 enforceNotIsolatedCaller("newUriPermissionOwner");
Dianne Hackborn7e269642010-08-25 19:50:20 -07005567 synchronized(this) {
5568 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5569 return owner.getExternalTokenLocked();
5570 }
5571 }
5572
5573 @Override
5574 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5575 Uri uri, int modeFlags) {
5576 synchronized(this) {
5577 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5578 if (owner == null) {
5579 throw new IllegalArgumentException("Unknown owner: " + token);
5580 }
5581 if (fromUid != Binder.getCallingUid()) {
5582 if (Binder.getCallingUid() != Process.myUid()) {
5583 // Only system code can grant URI permissions on behalf
5584 // of other users.
5585 throw new SecurityException("nice try");
5586 }
5587 }
5588 if (targetPkg == null) {
5589 throw new IllegalArgumentException("null target");
5590 }
5591 if (uri == null) {
5592 throw new IllegalArgumentException("null uri");
5593 }
5594
5595 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5596 }
5597 }
5598
5599 @Override
5600 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5601 synchronized(this) {
5602 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5603 if (owner == null) {
5604 throw new IllegalArgumentException("Unknown owner: " + token);
5605 }
5606
5607 if (uri == null) {
5608 owner.removeUriPermissionsLocked(mode);
5609 } else {
5610 owner.removeUriPermissionLocked(uri, mode);
5611 }
5612 }
5613 }
5614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005615 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5616 synchronized (this) {
5617 ProcessRecord app =
5618 who != null ? getRecordForAppLocked(who) : null;
5619 if (app == null) return;
5620
5621 Message msg = Message.obtain();
5622 msg.what = WAIT_FOR_DEBUGGER_MSG;
5623 msg.obj = app;
5624 msg.arg1 = waiting ? 1 : 0;
5625 mHandler.sendMessage(msg);
5626 }
5627 }
5628
5629 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005630 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5631 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005632 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn59325eb2012-05-09 18:45:20 -07005633 outInfo.totalMem = Process.getTotalMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005634 outInfo.threshold = homeAppMem;
5635 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5636 outInfo.hiddenAppThreshold = hiddenAppMem;
5637 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005638 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005639 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5640 ProcessList.VISIBLE_APP_ADJ);
5641 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5642 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 }
5644
5645 // =========================================================
5646 // TASK MANAGEMENT
5647 // =========================================================
5648
5649 public List getTasks(int maxNum, int flags,
5650 IThumbnailReceiver receiver) {
5651 ArrayList list = new ArrayList();
5652
5653 PendingThumbnailsRecord pending = null;
5654 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005655 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005656
5657 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005658 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005659 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5660 + ", receiver=" + receiver);
5661
5662 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5663 != PackageManager.PERMISSION_GRANTED) {
5664 if (receiver != null) {
5665 // If the caller wants to wait for pending thumbnails,
5666 // it ain't gonna get them.
5667 try {
5668 receiver.finished();
5669 } catch (RemoteException ex) {
5670 }
5671 }
5672 String msg = "Permission Denial: getTasks() from pid="
5673 + Binder.getCallingPid()
5674 + ", uid=" + Binder.getCallingUid()
5675 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005676 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005677 throw new SecurityException(msg);
5678 }
5679
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005680 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005681 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005682 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005683 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005684 TaskRecord curTask = null;
5685 int numActivities = 0;
5686 int numRunning = 0;
5687 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005688 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005690 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005691
5692 // Initialize state for next task if needed.
5693 if (top == null ||
5694 (top.state == ActivityState.INITIALIZING
5695 && top.task == r.task)) {
5696 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005697 curTask = r.task;
5698 numActivities = numRunning = 0;
5699 }
5700
5701 // Add 'r' into the current task.
5702 numActivities++;
5703 if (r.app != null && r.app.thread != null) {
5704 numRunning++;
5705 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706
Joe Onorato8a9b2202010-02-26 18:56:32 -08005707 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005708 TAG, r.intent.getComponent().flattenToShortString()
5709 + ": task=" + r.task);
5710
5711 // If the next one is a different task, generate a new
5712 // TaskInfo entry for what we have.
5713 if (next == null || next.task != curTask) {
5714 ActivityManager.RunningTaskInfo ci
5715 = new ActivityManager.RunningTaskInfo();
5716 ci.id = curTask.taskId;
5717 ci.baseActivity = r.intent.getComponent();
5718 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005719 if (top.thumbHolder != null) {
5720 ci.description = top.thumbHolder.lastDescription;
5721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005722 ci.numActivities = numActivities;
5723 ci.numRunning = numRunning;
5724 //System.out.println(
5725 // "#" + maxNum + ": " + " descr=" + ci.description);
5726 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005727 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005728 TAG, "State=" + top.state + "Idle=" + top.idle
5729 + " app=" + top.app
5730 + " thr=" + (top.app != null ? top.app.thread : null));
5731 if (top.state == ActivityState.RESUMED
5732 || top.state == ActivityState.PAUSING) {
5733 if (top.idle && top.app != null
5734 && top.app.thread != null) {
5735 topRecord = top;
5736 topThumbnail = top.app.thread;
5737 } else {
5738 top.thumbnailNeeded = true;
5739 }
5740 }
5741 if (pending == null) {
5742 pending = new PendingThumbnailsRecord(receiver);
5743 }
5744 pending.pendingRecords.add(top);
5745 }
5746 list.add(ci);
5747 maxNum--;
5748 top = null;
5749 }
5750 }
5751
5752 if (pending != null) {
5753 mPendingThumbnails.add(pending);
5754 }
5755 }
5756
Joe Onorato8a9b2202010-02-26 18:56:32 -08005757 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005758
5759 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005760 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005762 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005763 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005764 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005765 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005766 }
5767 }
5768
5769 if (pending == null && receiver != null) {
5770 // In this case all thumbnails were available and the client
5771 // is being asked to be told when the remaining ones come in...
5772 // which is unusually, since the top-most currently running
5773 // activity should never have a canned thumbnail! Oh well.
5774 try {
5775 receiver.finished();
5776 } catch (RemoteException ex) {
5777 }
5778 }
5779
5780 return list;
5781 }
5782
5783 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
Amith Yamasani82644082012-08-03 13:09:11 -07005784 int flags, int userId) {
Dianne Hackborn139748f2012-09-24 11:36:57 -07005785 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
5786 false, true, "getRecentTasks", null);
Amith Yamasani82644082012-08-03 13:09:11 -07005787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005788 synchronized (this) {
5789 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5790 "getRecentTasks()");
Dianne Hackborn8238e712012-04-24 11:15:40 -07005791 final boolean detailed = checkCallingPermission(
5792 android.Manifest.permission.GET_DETAILED_TASKS)
5793 == PackageManager.PERMISSION_GRANTED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005794
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005795 IPackageManager pm = AppGlobals.getPackageManager();
Amith Yamasani82644082012-08-03 13:09:11 -07005796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005797 final int N = mRecentTasks.size();
5798 ArrayList<ActivityManager.RecentTaskInfo> res
5799 = new ArrayList<ActivityManager.RecentTaskInfo>(
5800 maxNum < N ? maxNum : N);
5801 for (int i=0; i<N && maxNum > 0; i++) {
5802 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07005803 // Only add calling user's recent tasks
Amith Yamasani82644082012-08-03 13:09:11 -07005804 if (tr.userId != userId) continue;
Dianne Hackborn905577f2011-09-07 18:31:28 -07005805 // Return the entry if desired by the caller. We always return
5806 // the first entry, because callers always expect this to be the
Amith Yamasani742a6712011-05-04 14:49:28 -07005807 // foreground app. We may filter others if the caller has
Dianne Hackborn905577f2011-09-07 18:31:28 -07005808 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5809 // we should exclude the entry.
Amith Yamasani742a6712011-05-04 14:49:28 -07005810
Dianne Hackborn905577f2011-09-07 18:31:28 -07005811 if (i == 0
5812 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005813 || (tr.intent == null)
5814 || ((tr.intent.getFlags()
5815 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5816 ActivityManager.RecentTaskInfo rti
5817 = new ActivityManager.RecentTaskInfo();
5818 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005819 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005820 rti.baseIntent = new Intent(
5821 tr.intent != null ? tr.intent : tr.affinityIntent);
Dianne Hackborn8238e712012-04-24 11:15:40 -07005822 if (!detailed) {
5823 rti.baseIntent.replaceExtras((Bundle)null);
5824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005825 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005826 rti.description = tr.lastDescription;
5827
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005828 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5829 // Check whether this activity is currently available.
5830 try {
5831 if (rti.origActivity != null) {
Amith Yamasani82644082012-08-03 13:09:11 -07005832 if (pm.getActivityInfo(rti.origActivity, 0, userId)
Amith Yamasani483f3b02012-03-13 16:08:00 -07005833 == null) {
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005834 continue;
5835 }
5836 } else if (rti.baseIntent != null) {
5837 if (pm.queryIntentActivities(rti.baseIntent,
Amith Yamasani82644082012-08-03 13:09:11 -07005838 null, 0, userId) == null) {
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005839 continue;
5840 }
5841 }
5842 } catch (RemoteException e) {
5843 // Will never happen.
5844 }
5845 }
5846
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005847 res.add(rti);
5848 maxNum--;
5849 }
5850 }
5851 return res;
5852 }
5853 }
5854
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005855 private TaskRecord taskForIdLocked(int id) {
5856 final int N = mRecentTasks.size();
5857 for (int i=0; i<N; i++) {
5858 TaskRecord tr = mRecentTasks.get(i);
5859 if (tr.taskId == id) {
5860 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005861 }
5862 }
5863 return null;
5864 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005865
5866 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5867 synchronized (this) {
5868 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5869 "getTaskThumbnails()");
5870 TaskRecord tr = taskForIdLocked(id);
5871 if (tr != null) {
5872 return mMainStack.getTaskThumbnailsLocked(tr);
5873 }
5874 }
5875 return null;
5876 }
5877
Dianne Hackborn15491c62012-09-19 10:59:14 -07005878 public Bitmap getTaskTopThumbnail(int id) {
5879 synchronized (this) {
5880 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5881 "getTaskTopThumbnail()");
5882 TaskRecord tr = taskForIdLocked(id);
5883 if (tr != null) {
5884 return mMainStack.getTaskTopThumbnailLocked(tr);
5885 }
5886 }
5887 return null;
5888 }
5889
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005890 public boolean removeSubTask(int taskId, int subTaskIndex) {
5891 synchronized (this) {
5892 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5893 "removeSubTask()");
5894 long ident = Binder.clearCallingIdentity();
5895 try {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005896 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5897 true) != null;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005898 } finally {
5899 Binder.restoreCallingIdentity(ident);
5900 }
5901 }
5902 }
5903
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005904 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5905 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005906 Intent baseIntent = new Intent(
5907 tr.intent != null ? tr.intent : tr.affinityIntent);
5908 ComponentName component = baseIntent.getComponent();
5909 if (component == null) {
5910 Slog.w(TAG, "Now component for base intent of task: " + tr);
5911 return;
5912 }
5913
5914 // Find any running services associated with this app.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07005915 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005916
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005917 if (killProcesses) {
5918 // Find any running processes associated with this app.
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005919 final String pkg = component.getPackageName();
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005920 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005921 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5922 for (SparseArray<ProcessRecord> uids : pmap.values()) {
5923 for (int i=0; i<uids.size(); i++) {
5924 ProcessRecord proc = uids.valueAt(i);
5925 if (proc.userId != tr.userId) {
5926 continue;
5927 }
5928 if (!proc.pkgList.contains(pkg)) {
5929 continue;
5930 }
5931 procs.add(proc);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005932 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005933 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005934
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005935 // Kill the running processes.
5936 for (int i=0; i<procs.size(); i++) {
5937 ProcessRecord pr = procs.get(i);
5938 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5939 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
Dianne Hackbornb12e1352012-09-26 11:39:20 -07005940 EventLog.writeEvent(EventLogTags.AM_KILL, pr.userId, pr.pid,
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005941 pr.processName, pr.setAdj, "remove task");
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005942 pr.killedBackground = true;
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005943 Process.killProcessQuiet(pr.pid);
5944 } else {
5945 pr.waitingToKill = "remove task";
5946 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005947 }
5948 }
5949 }
5950
5951 public boolean removeTask(int taskId, int flags) {
5952 synchronized (this) {
5953 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5954 "removeTask()");
5955 long ident = Binder.clearCallingIdentity();
5956 try {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005957 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5958 false);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005959 if (r != null) {
5960 mRecentTasks.remove(r.task);
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005961 cleanUpRemovedTaskLocked(r.task, flags);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005962 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005963 } else {
5964 TaskRecord tr = null;
5965 int i=0;
5966 while (i < mRecentTasks.size()) {
5967 TaskRecord t = mRecentTasks.get(i);
5968 if (t.taskId == taskId) {
5969 tr = t;
5970 break;
5971 }
5972 i++;
5973 }
5974 if (tr != null) {
5975 if (tr.numActivities <= 0) {
5976 // Caller is just removing a recent task that is
5977 // not actively running. That is easy!
5978 mRecentTasks.remove(i);
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005979 cleanUpRemovedTaskLocked(tr, flags);
5980 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005981 } else {
5982 Slog.w(TAG, "removeTask: task " + taskId
5983 + " does not have activities to remove, "
5984 + " but numActivities=" + tr.numActivities
5985 + ": " + tr);
5986 }
5987 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005988 }
5989 } finally {
5990 Binder.restoreCallingIdentity(ident);
5991 }
5992 }
5993 return false;
5994 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5997 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005998 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005999 TaskRecord jt = startTask;
6000
6001 // First look backwards
6002 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006003 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006004 if (r.task != jt) {
6005 jt = r.task;
6006 if (affinity.equals(jt.affinity)) {
6007 return j;
6008 }
6009 }
6010 }
6011
6012 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006013 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006014 jt = startTask;
6015 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006016 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006017 if (r.task != jt) {
6018 if (affinity.equals(jt.affinity)) {
6019 return j;
6020 }
6021 jt = r.task;
6022 }
6023 }
6024
6025 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006026 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006027 return N-1;
6028 }
6029
6030 return -1;
6031 }
6032
6033 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07006034 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006035 */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07006036 public void moveTaskToFront(int task, int flags, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006037 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6038 "moveTaskToFront()");
6039
6040 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006041 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6042 Binder.getCallingUid(), "Task to front")) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07006043 ActivityOptions.abort(options);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006044 return;
6045 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006046 final long origId = Binder.clearCallingIdentity();
6047 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006048 TaskRecord tr = taskForIdLocked(task);
6049 if (tr != null) {
6050 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6051 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006052 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006053 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6054 // Caller wants the home activity moved with it. To accomplish this,
6055 // we'll just move the home task to the top first.
6056 mMainStack.moveHomeToFrontLocked();
6057 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07006058 mMainStack.moveTaskToFrontLocked(tr, null, options);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07006059 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006060 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006061 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
6062 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006063 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08006064 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
6065 mMainStack.mUserLeaving = true;
6066 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08006067 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
6068 // Caller wants the home activity moved with it. To accomplish this,
6069 // we'll just move the home task to the top first.
6070 mMainStack.moveHomeToFrontLocked();
6071 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07006072 mMainStack.moveTaskToFrontLocked(hr.task, null, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006073 return;
6074 }
6075 }
6076 } finally {
6077 Binder.restoreCallingIdentity(origId);
6078 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07006079 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006080 }
6081 }
6082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006083 public void moveTaskToBack(int task) {
6084 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6085 "moveTaskToBack()");
6086
6087 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006088 if (mMainStack.mResumedActivity != null
6089 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006090 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6091 Binder.getCallingUid(), "Task to back")) {
6092 return;
6093 }
6094 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006095 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006096 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006097 Binder.restoreCallingIdentity(origId);
6098 }
6099 }
6100
6101 /**
6102 * Moves an activity, and all of the other activities within the same task, to the bottom
6103 * of the history stack. The activity's order within the task is unchanged.
6104 *
6105 * @param token A reference to the activity we wish to move
6106 * @param nonRoot If false then this only works if the activity is the root
6107 * of a task; if true it will work for any activity in a task.
6108 * @return Returns true if the move completed, false if not.
6109 */
6110 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006111 enforceNotIsolatedCaller("moveActivityTaskToBack");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006112 synchronized(this) {
6113 final long origId = Binder.clearCallingIdentity();
6114 int taskId = getTaskForActivityLocked(token, !nonRoot);
6115 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006116 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006117 }
6118 Binder.restoreCallingIdentity(origId);
6119 }
6120 return false;
6121 }
6122
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006123 public void moveTaskBackwards(int task) {
6124 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
6125 "moveTaskBackwards()");
6126
6127 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07006128 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
6129 Binder.getCallingUid(), "Task backwards")) {
6130 return;
6131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006132 final long origId = Binder.clearCallingIdentity();
6133 moveTaskBackwardsLocked(task);
6134 Binder.restoreCallingIdentity(origId);
6135 }
6136 }
6137
6138 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006139 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006140 }
6141
6142 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
6143 synchronized(this) {
6144 return getTaskForActivityLocked(token, onlyRoot);
6145 }
6146 }
6147
6148 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006149 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 TaskRecord lastTask = null;
6151 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006152 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08006153 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006154 if (!onlyRoot || lastTask != r.task) {
6155 return r.task.taskId;
6156 }
6157 return -1;
6158 }
6159 lastTask = r.task;
6160 }
6161
6162 return -1;
6163 }
6164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006165 // =========================================================
6166 // THUMBNAILS
6167 // =========================================================
6168
6169 public void reportThumbnail(IBinder token,
6170 Bitmap thumbnail, CharSequence description) {
6171 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
6172 final long origId = Binder.clearCallingIdentity();
6173 sendPendingThumbnail(null, token, thumbnail, description, true);
6174 Binder.restoreCallingIdentity(origId);
6175 }
6176
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006177 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006178 Bitmap thumbnail, CharSequence description, boolean always) {
6179 TaskRecord task = null;
6180 ArrayList receivers = null;
6181
6182 //System.out.println("Send pending thumbnail: " + r);
6183
6184 synchronized(this) {
6185 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006186 r = mMainStack.isInStackLocked(token);
6187 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006188 return;
6189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006190 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07006191 if (thumbnail == null && r.thumbHolder != null) {
6192 thumbnail = r.thumbHolder.lastThumbnail;
6193 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006194 }
6195 if (thumbnail == null && !always) {
6196 // If there is no thumbnail, and this entry is not actually
6197 // going away, then abort for now and pick up the next
6198 // thumbnail we get.
6199 return;
6200 }
6201 task = r.task;
6202
6203 int N = mPendingThumbnails.size();
6204 int i=0;
6205 while (i<N) {
6206 PendingThumbnailsRecord pr =
6207 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6208 //System.out.println("Looking in " + pr.pendingRecords);
6209 if (pr.pendingRecords.remove(r)) {
6210 if (receivers == null) {
6211 receivers = new ArrayList();
6212 }
6213 receivers.add(pr);
6214 if (pr.pendingRecords.size() == 0) {
6215 pr.finished = true;
6216 mPendingThumbnails.remove(i);
6217 N--;
6218 continue;
6219 }
6220 }
6221 i++;
6222 }
6223 }
6224
6225 if (receivers != null) {
6226 final int N = receivers.size();
6227 for (int i=0; i<N; i++) {
6228 try {
6229 PendingThumbnailsRecord pr =
6230 (PendingThumbnailsRecord)receivers.get(i);
6231 pr.receiver.newThumbnail(
6232 task != null ? task.taskId : -1, thumbnail, description);
6233 if (pr.finished) {
6234 pr.receiver.finished();
6235 }
6236 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006237 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006238 }
6239 }
6240 }
6241 }
6242
6243 // =========================================================
6244 // CONTENT PROVIDERS
6245 // =========================================================
6246
Jeff Brown10e89712011-07-08 18:52:57 -07006247 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6248 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006250 providers = AppGlobals.getPackageManager().
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006251 queryContentProviders(app.processName, app.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006252 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006253 } catch (RemoteException ex) {
6254 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006255 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006256 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6257 int userId = app.userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006258 if (providers != null) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006259 int N = providers.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006260 for (int i=0; i<N; i++) {
6261 ProviderInfo cpi =
6262 (ProviderInfo)providers.get(i);
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006263 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6264 cpi.name, cpi.flags);
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07006265 if (singleton && UserHandle.getUserId(app.uid) != 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006266 // This is a singleton provider, but a user besides the
6267 // default user is asking to initialize a process it runs
6268 // in... well, no, it doesn't actually run in this process,
6269 // it runs in the process of the default user. Get rid of it.
6270 providers.remove(i);
6271 N--;
6272 continue;
6273 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006274
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006275 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006276 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006277 if (cpr == null) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006278 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
Amith Yamasani742a6712011-05-04 14:49:28 -07006279 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006280 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006281 if (DEBUG_MU)
6282 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006283 app.pubProviders.put(cpi.name, cpr);
6284 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07006285 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006286 }
6287 }
6288 return providers;
6289 }
6290
Jeff Sharkey110a6b62012-03-12 11:12:41 -07006291 /**
6292 * Check if {@link ProcessRecord} has a possible chance at accessing the
6293 * given {@link ProviderInfo}. Final permission checking is always done
6294 * in {@link ContentProvider}.
6295 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006296 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07006297 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006298 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006299 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006300 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006301 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006302 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006303 return null;
6304 }
6305 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006306 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006307 == PackageManager.PERMISSION_GRANTED) {
6308 return null;
6309 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006310
6311 PathPermission[] pps = cpi.pathPermissions;
6312 if (pps != null) {
6313 int i = pps.length;
6314 while (i > 0) {
6315 i--;
6316 PathPermission pp = pps[i];
6317 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006318 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006319 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006320 return null;
6321 }
6322 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006323 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006324 == PackageManager.PERMISSION_GRANTED) {
6325 return null;
6326 }
6327 }
6328 }
6329
Dianne Hackbornb424b632010-08-18 15:59:05 -07006330 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6331 if (perms != null) {
6332 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6333 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6334 return null;
6335 }
6336 }
6337 }
6338
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006339 String msg;
6340 if (!cpi.exported) {
6341 msg = "Permission Denial: opening provider " + cpi.name
6342 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6343 + ", uid=" + callingUid + ") that is not exported from uid "
6344 + cpi.applicationInfo.uid;
6345 } else {
6346 msg = "Permission Denial: opening provider " + cpi.name
6347 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6348 + ", uid=" + callingUid + ") requires "
6349 + cpi.readPermission + " or " + cpi.writePermission;
6350 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006351 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006352 return msg;
6353 }
6354
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006355 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6356 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006357 if (r != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006358 for (int i=0; i<r.conProviders.size(); i++) {
6359 ContentProviderConnection conn = r.conProviders.get(i);
6360 if (conn.provider == cpr) {
6361 if (DEBUG_PROVIDER) Slog.v(TAG,
6362 "Adding provider requested by "
6363 + r.processName + " from process "
6364 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6365 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6366 if (stable) {
6367 conn.stableCount++;
6368 conn.numStableIncs++;
6369 } else {
6370 conn.unstableCount++;
6371 conn.numUnstableIncs++;
6372 }
6373 return conn;
6374 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006375 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006376 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6377 if (stable) {
6378 conn.stableCount = 1;
6379 conn.numStableIncs = 1;
6380 } else {
6381 conn.unstableCount = 1;
6382 conn.numUnstableIncs = 1;
6383 }
6384 cpr.connections.add(conn);
6385 r.conProviders.add(conn);
6386 return conn;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006387 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006388 cpr.addExternalProcessHandleLocked(externalProcessToken);
6389 return null;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006390 }
6391
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006392 boolean decProviderCountLocked(ContentProviderConnection conn,
6393 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6394 if (conn != null) {
6395 cpr = conn.provider;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006396 if (DEBUG_PROVIDER) Slog.v(TAG,
6397 "Removing provider requested by "
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006398 + conn.client.processName + " from process "
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006399 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006400 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6401 if (stable) {
6402 conn.stableCount--;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006403 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006404 conn.unstableCount--;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006405 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006406 if (conn.stableCount == 0 && conn.unstableCount == 0) {
6407 cpr.connections.remove(conn);
6408 conn.client.conProviders.remove(conn);
6409 return true;
6410 }
6411 return false;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006412 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006413 cpr.removeExternalProcessHandleLocked(externalProcessToken);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006414 return false;
6415 }
6416
Amith Yamasani742a6712011-05-04 14:49:28 -07006417 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
Dianne Hackborn41203752012-08-31 14:05:51 -07006418 String name, IBinder token, boolean stable, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006419 ContentProviderRecord cpr;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006420 ContentProviderConnection conn = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006421 ProviderInfo cpi = null;
6422
6423 synchronized(this) {
6424 ProcessRecord r = null;
6425 if (caller != null) {
6426 r = getRecordForAppLocked(caller);
6427 if (r == null) {
6428 throw new SecurityException(
6429 "Unable to find app for caller " + caller
6430 + " (pid=" + Binder.getCallingPid()
6431 + ") when getting content provider " + name);
6432 }
6433 }
6434
6435 // First check if this content provider has been published...
Amith Yamasani742a6712011-05-04 14:49:28 -07006436 cpr = mProviderMap.getProviderByName(name, userId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006437 boolean providerRunning = cpr != null;
6438 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006439 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07006440 String msg;
6441 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6442 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006443 }
6444
6445 if (r != null && cpr.canRunHere(r)) {
6446 // This provider has been published or is in the process
6447 // of being published... but it is also allowed to run
6448 // in the caller's process, so don't make a connection
6449 // and just let the caller instantiate its own instance.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006450 ContentProviderHolder holder = cpr.newHolder(null);
6451 // don't give caller the provider object, it needs
6452 // to make its own.
6453 holder.provider = null;
6454 return holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006455 }
6456
6457 final long origId = Binder.clearCallingIdentity();
6458
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006459 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006460 // return it right away.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006461 conn = incProviderCountLocked(r, cpr, token, stable);
6462 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006463 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006464 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07006465 // make sure to count it as being accessed and thus
6466 // back up on the LRU list. This is good because
6467 // content providers are often expensive to start.
Dianne Hackbornb12e1352012-09-26 11:39:20 -07006468 updateLruProcessLocked(cpr.proc, false);
Dianne Hackborn906497c2010-05-10 15:57:38 -07006469 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07006470 }
6471
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006472 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006473 if (false) {
6474 if (cpr.name.flattenToShortString().equals(
6475 "com.android.providers.calendar/.CalendarProvider2")) {
6476 Slog.v(TAG, "****************** KILLING "
6477 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006478 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006479 }
6480 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006481 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006482 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6483 // NOTE: there is still a race here where a signal could be
6484 // pending on the process even though we managed to update its
6485 // adj level. Not sure what to do about this, but at least
6486 // the race is now smaller.
6487 if (!success) {
6488 // Uh oh... it looks like the provider's process
6489 // has been killed on us. We need to wait for a new
6490 // process to be started, and make sure its death
6491 // doesn't kill our process.
6492 Slog.i(TAG,
6493 "Existing provider " + cpr.name.flattenToShortString()
6494 + " is crashing; detaching " + r);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006495 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006496 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006497 if (!lastRef) {
6498 // This wasn't the last ref our process had on
6499 // the provider... we have now been killed, bail.
6500 return null;
6501 }
6502 providerRunning = false;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006503 conn = null;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006504 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006505 }
6506
6507 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006508 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006509
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006510 boolean singleton;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006511 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006512 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006513 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006514 resolveContentProvider(name,
Amith Yamasani483f3b02012-03-13 16:08:00 -07006515 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006516 } catch (RemoteException ex) {
6517 }
6518 if (cpi == null) {
6519 return null;
6520 }
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006521 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6522 cpi.name, cpi.flags);
6523 if (singleton) {
Amith Yamasania4a54e22012-04-16 15:44:19 -07006524 userId = 0;
6525 }
Amith Yamasani483f3b02012-03-13 16:08:00 -07006526 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07006527
Dianne Hackbornb424b632010-08-18 15:59:05 -07006528 String msg;
6529 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6530 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006531 }
6532
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006533 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006534 && !cpi.processName.equals("system")) {
6535 // If this content provider does not run in the system
6536 // process, and the system is not yet ready to run other
6537 // processes, then fail fast instead of hanging.
6538 throw new IllegalArgumentException(
6539 "Attempt to launch content provider before system ready");
6540 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006541
Dianne Hackborn80a4af22012-08-27 19:18:31 -07006542 // Make sure that the user who owns this provider is started. If not,
6543 // we don't want to allow it to run.
6544 if (mStartedUsers.get(userId) == null) {
6545 Slog.w(TAG, "Unable to launch app "
6546 + cpi.applicationInfo.packageName + "/"
6547 + cpi.applicationInfo.uid + " for provider "
6548 + name + ": user " + userId + " is stopped");
6549 return null;
6550 }
6551
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006552 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani483f3b02012-03-13 16:08:00 -07006553 cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006554 final boolean firstClass = cpr == null;
6555 if (firstClass) {
6556 try {
6557 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006558 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006559 getApplicationInfo(
6560 cpi.applicationInfo.packageName,
Amith Yamasani483f3b02012-03-13 16:08:00 -07006561 STOCK_PM_FLAGS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006562 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006563 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006564 + cpi.name);
6565 return null;
6566 }
Amith Yamasani483f3b02012-03-13 16:08:00 -07006567 ai = getAppInfoForUser(ai, userId);
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006568 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 } catch (RemoteException ex) {
6570 // pm is in same process, this will never happen.
6571 }
6572 }
6573
6574 if (r != null && cpr.canRunHere(r)) {
6575 // If this is a multiprocess provider, then just return its
6576 // info and allow the caller to instantiate it. Only do
6577 // this if the provider is the same user as the caller's
6578 // process, or can run as root (so can be in any process).
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006579 return cpr.newHolder(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006580 }
6581
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006582 if (DEBUG_PROVIDER) {
6583 RuntimeException e = new RuntimeException("here");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006584 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006585 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006586 }
6587
6588 // This is single process, and our app is now connecting to it.
6589 // See if we are already in the process of launching this
6590 // provider.
6591 final int N = mLaunchingProviders.size();
6592 int i;
6593 for (i=0; i<N; i++) {
6594 if (mLaunchingProviders.get(i) == cpr) {
6595 break;
6596 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006597 }
6598
6599 // If the provider is not already being launched, then get it
6600 // started.
6601 if (i >= N) {
6602 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006603
6604 try {
6605 // Content provider is now in use, its package can't be stopped.
6606 try {
6607 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -07006608 cpr.appInfo.packageName, false, userId);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006609 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006610 } catch (IllegalArgumentException e) {
6611 Slog.w(TAG, "Failed trying to unstop package "
6612 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006613 }
6614
6615 ProcessRecord proc = startProcessLocked(cpi.processName,
6616 cpr.appInfo, false, 0, "content provider",
6617 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006618 cpi.name), false, false);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006619 if (proc == null) {
6620 Slog.w(TAG, "Unable to launch app "
6621 + cpi.applicationInfo.packageName + "/"
6622 + cpi.applicationInfo.uid + " for provider "
6623 + name + ": process is bad");
6624 return null;
6625 }
6626 cpr.launchingApp = proc;
6627 mLaunchingProviders.add(cpr);
6628 } finally {
6629 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006630 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006631 }
6632
6633 // Make sure the provider is published (the same provider class
6634 // may be published under multiple names).
6635 if (firstClass) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006636 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006637 }
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006638
Amith Yamasani742a6712011-05-04 14:49:28 -07006639 mProviderMap.putProviderByName(name, cpr);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006640 conn = incProviderCountLocked(r, cpr, token, stable);
6641 if (conn != null) {
6642 conn.waiting = true;
6643 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 }
6645 }
6646
6647 // Wait for the provider to be published...
6648 synchronized (cpr) {
6649 while (cpr.provider == null) {
6650 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006651 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006652 + cpi.applicationInfo.packageName + "/"
6653 + cpi.applicationInfo.uid + " for provider "
6654 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006655 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07006656 UserHandle.getUserId(cpi.applicationInfo.uid),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006657 cpi.applicationInfo.packageName,
6658 cpi.applicationInfo.uid, name);
6659 return null;
6660 }
6661 try {
Amith Yamasani742a6712011-05-04 14:49:28 -07006662 if (DEBUG_MU) {
6663 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6664 + cpr.launchingApp);
6665 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006666 if (conn != null) {
6667 conn.waiting = true;
6668 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006669 cpr.wait();
6670 } catch (InterruptedException ex) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006671 } finally {
6672 if (conn != null) {
6673 conn.waiting = false;
6674 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006675 }
6676 }
6677 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006678 return cpr != null ? cpr.newHolder(conn) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006679 }
6680
6681 public final ContentProviderHolder getContentProvider(
Jeff Sharkey6d515712012-09-20 16:06:08 -07006682 IApplicationThread caller, String name, int userId, boolean stable) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006683 enforceNotIsolatedCaller("getContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006684 if (caller == null) {
6685 String msg = "null IApplicationThread when getting content provider "
6686 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006687 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006688 throw new SecurityException(msg);
6689 }
6690
Dianne Hackborn139748f2012-09-24 11:36:57 -07006691 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Jeff Sharkey6d515712012-09-20 16:06:08 -07006692 false, true, "getContentProvider", null);
6693 return getContentProviderImpl(caller, name, null, stable, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006694 }
6695
Jeff Sharkey6d515712012-09-20 16:06:08 -07006696 public ContentProviderHolder getContentProviderExternal(
6697 String name, int userId, IBinder token) {
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006698 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6699 "Do not have permission in call getContentProviderExternal()");
Dianne Hackborn139748f2012-09-24 11:36:57 -07006700 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
Jeff Sharkey6d515712012-09-20 16:06:08 -07006701 false, true, "getContentProvider", null);
6702 return getContentProviderExternalUnchecked(name, token, userId);
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006703 }
6704
Dianne Hackborn41203752012-08-31 14:05:51 -07006705 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6706 IBinder token, int userId) {
6707 return getContentProviderImpl(null, name, token, true, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006708 }
6709
6710 /**
6711 * Drop a content provider from a ProcessRecord's bookkeeping
6712 * @param cpr
6713 */
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006714 public void removeContentProvider(IBinder connection, boolean stable) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006715 enforceNotIsolatedCaller("removeContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006716 synchronized (this) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006717 ContentProviderConnection conn;
6718 try {
6719 conn = (ContentProviderConnection)connection;
6720 } catch (ClassCastException e) {
6721 String msg ="removeContentProvider: " + connection
6722 + " not a ContentProviderConnection";
6723 Slog.w(TAG, msg);
6724 throw new IllegalArgumentException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006725 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006726 if (conn == null) {
6727 throw new NullPointerException("connection is null");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006728 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006729 if (decProviderCountLocked(conn, null, null, stable)) {
6730 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006731 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 }
6733 }
6734
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006735 public void removeContentProviderExternal(String name, IBinder token) {
6736 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6737 "Do not have permission in call removeContentProviderExternal()");
Dianne Hackborn41203752012-08-31 14:05:51 -07006738 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006739 }
6740
Dianne Hackborn41203752012-08-31 14:05:51 -07006741 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006742 synchronized (this) {
Dianne Hackborn41203752012-08-31 14:05:51 -07006743 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006744 if(cpr == null) {
6745 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006746 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006747 return;
6748 }
6749
6750 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006751 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Dianne Hackborn41203752012-08-31 14:05:51 -07006752 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006753 if (localCpr.hasExternalProcessHandles()) {
6754 if (localCpr.removeExternalProcessHandleLocked(token)) {
6755 updateOomAdjLocked();
6756 } else {
6757 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6758 + " with no external reference for token: "
6759 + token + ".");
6760 }
6761 } else {
6762 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6763 + " with no external references.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006764 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006765 }
6766 }
6767
6768 public final void publishContentProviders(IApplicationThread caller,
6769 List<ContentProviderHolder> providers) {
6770 if (providers == null) {
6771 return;
6772 }
6773
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006774 enforceNotIsolatedCaller("publishContentProviders");
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006775 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006776 final ProcessRecord r = getRecordForAppLocked(caller);
Amith Yamasani742a6712011-05-04 14:49:28 -07006777 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006778 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006779 if (r == null) {
6780 throw new SecurityException(
6781 "Unable to find app for caller " + caller
6782 + " (pid=" + Binder.getCallingPid()
6783 + ") when publishing content providers");
6784 }
6785
6786 final long origId = Binder.clearCallingIdentity();
6787
6788 final int N = providers.size();
6789 for (int i=0; i<N; i++) {
6790 ContentProviderHolder src = providers.get(i);
6791 if (src == null || src.info == null || src.provider == null) {
6792 continue;
6793 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006794 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006795 if (DEBUG_MU)
6796 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006797 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006798 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006799 mProviderMap.putProviderByClass(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006800 String names[] = dst.info.authority.split(";");
6801 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006802 mProviderMap.putProviderByName(names[j], dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006803 }
6804
6805 int NL = mLaunchingProviders.size();
6806 int j;
6807 for (j=0; j<NL; j++) {
6808 if (mLaunchingProviders.get(j) == dst) {
6809 mLaunchingProviders.remove(j);
6810 j--;
6811 NL--;
6812 }
6813 }
6814 synchronized (dst) {
6815 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006816 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006817 dst.notifyAll();
6818 }
6819 updateOomAdjLocked(r);
6820 }
6821 }
6822
6823 Binder.restoreCallingIdentity(origId);
6824 }
6825 }
6826
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006827 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6828 ContentProviderConnection conn;
6829 try {
6830 conn = (ContentProviderConnection)connection;
6831 } catch (ClassCastException e) {
6832 String msg ="refContentProvider: " + connection
6833 + " not a ContentProviderConnection";
6834 Slog.w(TAG, msg);
6835 throw new IllegalArgumentException(msg);
6836 }
6837 if (conn == null) {
6838 throw new NullPointerException("connection is null");
6839 }
6840
6841 synchronized (this) {
6842 if (stable > 0) {
6843 conn.numStableIncs += stable;
6844 }
6845 stable = conn.stableCount + stable;
6846 if (stable < 0) {
6847 throw new IllegalStateException("stableCount < 0: " + stable);
6848 }
6849
6850 if (unstable > 0) {
6851 conn.numUnstableIncs += unstable;
6852 }
6853 unstable = conn.unstableCount + unstable;
6854 if (unstable < 0) {
6855 throw new IllegalStateException("unstableCount < 0: " + unstable);
6856 }
6857
6858 if ((stable+unstable) <= 0) {
6859 throw new IllegalStateException("ref counts can't go to zero here: stable="
6860 + stable + " unstable=" + unstable);
6861 }
6862 conn.stableCount = stable;
6863 conn.unstableCount = unstable;
6864 return !conn.dead;
6865 }
6866 }
6867
6868 public void unstableProviderDied(IBinder connection) {
6869 ContentProviderConnection conn;
6870 try {
6871 conn = (ContentProviderConnection)connection;
6872 } catch (ClassCastException e) {
6873 String msg ="refContentProvider: " + connection
6874 + " not a ContentProviderConnection";
6875 Slog.w(TAG, msg);
6876 throw new IllegalArgumentException(msg);
6877 }
6878 if (conn == null) {
6879 throw new NullPointerException("connection is null");
6880 }
6881
6882 // Safely retrieve the content provider associated with the connection.
6883 IContentProvider provider;
6884 synchronized (this) {
6885 provider = conn.provider.provider;
6886 }
6887
6888 if (provider == null) {
6889 // Um, yeah, we're way ahead of you.
6890 return;
6891 }
6892
6893 // Make sure the caller is being honest with us.
6894 if (provider.asBinder().pingBinder()) {
6895 // Er, no, still looks good to us.
6896 synchronized (this) {
6897 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6898 + " says " + conn + " died, but we don't agree");
6899 return;
6900 }
6901 }
6902
6903 // Well look at that! It's dead!
6904 synchronized (this) {
6905 if (conn.provider.provider != provider) {
6906 // But something changed... good enough.
6907 return;
6908 }
6909
6910 ProcessRecord proc = conn.provider.proc;
6911 if (proc == null || proc.thread == null) {
6912 // Seems like the process is already cleaned up.
6913 return;
6914 }
6915
6916 // As far as we're concerned, this is just like receiving a
6917 // death notification... just a bit prematurely.
6918 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6919 + ") early provider death");
Dianne Hackbornbd145db2012-06-05 16:20:46 -07006920 final long ident = Binder.clearCallingIdentity();
6921 try {
6922 appDiedLocked(proc, proc.pid, proc.thread);
6923 } finally {
6924 Binder.restoreCallingIdentity(ident);
6925 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006926 }
6927 }
6928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006929 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006930 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006931 synchronized (mSelf) {
6932 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6933 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006934 if (providers != null) {
6935 for (int i=providers.size()-1; i>=0; i--) {
6936 ProviderInfo pi = (ProviderInfo)providers.get(i);
6937 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6938 Slog.w(TAG, "Not installing system proc provider " + pi.name
6939 + ": not system .apk");
6940 providers.remove(i);
6941 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006942 }
6943 }
6944 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006945 if (providers != null) {
6946 mSystemThread.installSystemProviders(providers);
6947 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006948
6949 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006950
6951 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 }
6953
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006954 /**
6955 * Allows app to retrieve the MIME type of a URI without having permission
6956 * to access its content provider.
6957 *
6958 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6959 *
6960 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6961 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6962 */
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07006963 public String getProviderMimeType(Uri uri, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006964 enforceNotIsolatedCaller("getProviderMimeType");
Dianne Hackborn139748f2012-09-24 11:36:57 -07006965 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07006966 userId, false, true, "getProviderMimeType", null);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006967 final String name = uri.getAuthority();
6968 final long ident = Binder.clearCallingIdentity();
6969 ContentProviderHolder holder = null;
6970
6971 try {
Dianne Hackborn41203752012-08-31 14:05:51 -07006972 holder = getContentProviderExternalUnchecked(name, null, userId);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006973 if (holder != null) {
6974 return holder.provider.getType(uri);
6975 }
6976 } catch (RemoteException e) {
6977 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6978 return null;
6979 } finally {
6980 if (holder != null) {
Dianne Hackborn41203752012-08-31 14:05:51 -07006981 removeContentProviderExternalUnchecked(name, null, userId);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006982 }
6983 Binder.restoreCallingIdentity(ident);
6984 }
6985
6986 return null;
6987 }
6988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006989 // =========================================================
6990 // GLOBAL MANAGEMENT
6991 // =========================================================
6992
6993 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006994 ApplicationInfo info, String customProcess, boolean isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006995 String proc = customProcess != null ? customProcess : info.processName;
6996 BatteryStatsImpl.Uid.Proc ps = null;
6997 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006998 int uid = info.uid;
6999 if (isolated) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07007000 int userId = UserHandle.getUserId(uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007001 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
7002 uid = 0;
7003 while (true) {
7004 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
7005 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
7006 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
7007 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07007008 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007009 mNextIsolatedProcessUid++;
7010 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
7011 // No process for this uid, use it.
7012 break;
7013 }
7014 stepsLeft--;
7015 if (stepsLeft <= 0) {
7016 return null;
7017 }
7018 }
7019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007020 synchronized (stats) {
7021 ps = stats.getProcessStatsLocked(info.uid, proc);
7022 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007023 return new ProcessRecord(ps, thread, info, proc, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007024 }
7025
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007026 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
7027 ProcessRecord app;
7028 if (!isolated) {
7029 app = getProcessRecordLocked(info.processName, info.uid);
7030 } else {
7031 app = null;
7032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007033
7034 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007035 app = newProcessRecordLocked(null, info, null, isolated);
7036 mProcessNames.put(info.processName, app.uid, app);
7037 if (isolated) {
7038 mIsolatedProcesses.put(app.uid, app);
7039 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -07007040 updateLruProcessLocked(app, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007041 }
7042
Dianne Hackborne7f97212011-02-24 14:40:20 -08007043 // This package really, really can not be stopped.
7044 try {
7045 AppGlobals.getPackageManager().setPackageStoppedState(
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07007046 info.packageName, false, UserHandle.getUserId(app.uid));
Dianne Hackborne7f97212011-02-24 14:40:20 -08007047 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08007048 } catch (IllegalArgumentException e) {
7049 Slog.w(TAG, "Failed trying to unstop package "
7050 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08007051 }
7052
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007053 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
7054 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
7055 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007056 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007057 }
7058 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
7059 mPersistentStartingProcesses.add(app);
7060 startProcessLocked(app, "added application", app.processName);
7061 }
7062
7063 return app;
7064 }
7065
7066 public void unhandledBack() {
7067 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
7068 "unhandledBack()");
7069
7070 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007071 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08007072 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007073 TAG, "Performing unhandledBack(): stack size = " + count);
7074 if (count > 1) {
7075 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007076 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07007077 count-1, Activity.RESULT_CANCELED, null, "unhandled-back", true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007078 Binder.restoreCallingIdentity(origId);
7079 }
7080 }
7081 }
7082
7083 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007084 enforceNotIsolatedCaller("openContentUri");
Dianne Hackborn41203752012-08-31 14:05:51 -07007085 final int userId = UserHandle.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007086 String name = uri.getAuthority();
Dianne Hackborn41203752012-08-31 14:05:51 -07007087 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007088 ParcelFileDescriptor pfd = null;
7089 if (cph != null) {
7090 // We record the binder invoker's uid in thread-local storage before
7091 // going to the content provider to open the file. Later, in the code
7092 // that handles all permissions checks, we look for this uid and use
7093 // that rather than the Activity Manager's own uid. The effect is that
7094 // we do the check against the caller's permissions even though it looks
7095 // to the content provider like the Activity Manager itself is making
7096 // the request.
7097 sCallerIdentity.set(new Identity(
7098 Binder.getCallingPid(), Binder.getCallingUid()));
7099 try {
7100 pfd = cph.provider.openFile(uri, "r");
7101 } catch (FileNotFoundException e) {
7102 // do nothing; pfd will be returned null
7103 } finally {
7104 // Ensure that whatever happens, we clean up the identity state
7105 sCallerIdentity.remove();
7106 }
7107
7108 // We've got the fd now, so we're done with the provider.
Dianne Hackborn41203752012-08-31 14:05:51 -07007109 removeContentProviderExternalUnchecked(name, null, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007110 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007111 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007112 }
7113 return pfd;
7114 }
7115
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007116 // Actually is sleeping or shutting down or whatever else in the future
7117 // is an inactive state.
7118 public boolean isSleeping() {
7119 return mSleeping || mShuttingDown;
7120 }
7121
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007122 public void goingToSleep() {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007123 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7124 != PackageManager.PERMISSION_GRANTED) {
7125 throw new SecurityException("Requires permission "
7126 + android.Manifest.permission.DEVICE_POWER);
7127 }
7128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007129 synchronized(this) {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007130 mWentToSleep = true;
Jeff Brownc042ee22012-05-08 13:03:42 -07007131 updateEventDispatchingLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007132
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007133 if (!mSleeping) {
7134 mSleeping = true;
7135 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007136
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007137 // Initialize the wake times of all processes.
7138 checkExcessivePowerUsageLocked(false);
7139 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7140 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
7141 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
7142 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007143 }
7144 }
7145
Dianne Hackborn55280a92009-05-07 15:53:46 -07007146 public boolean shutdown(int timeout) {
7147 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
7148 != PackageManager.PERMISSION_GRANTED) {
7149 throw new SecurityException("Requires permission "
7150 + android.Manifest.permission.SHUTDOWN);
7151 }
7152
7153 boolean timedout = false;
7154
7155 synchronized(this) {
7156 mShuttingDown = true;
Jeff Brownc042ee22012-05-08 13:03:42 -07007157 updateEventDispatchingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07007158
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007159 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007160 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07007161 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007162 while (mMainStack.mResumedActivity != null
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08007163 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07007164 long delay = endTime - System.currentTimeMillis();
7165 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007166 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07007167 timedout = true;
7168 break;
7169 }
7170 try {
7171 this.wait();
7172 } catch (InterruptedException e) {
7173 }
7174 }
7175 }
7176 }
7177
7178 mUsageStatsService.shutdown();
7179 mBatteryStatsService.shutdown();
7180
7181 return timedout;
7182 }
7183
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007184 public final void activitySlept(IBinder token) {
7185 if (localLOGV) Slog.v(
7186 TAG, "Activity slept: token=" + token);
7187
7188 ActivityRecord r = null;
7189
7190 final long origId = Binder.clearCallingIdentity();
7191
7192 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007193 r = mMainStack.isInStackLocked(token);
7194 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08007195 mMainStack.activitySleptLocked(r);
7196 }
7197 }
7198
7199 Binder.restoreCallingIdentity(origId);
7200 }
7201
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007202 private void comeOutOfSleepIfNeededLocked() {
7203 if (!mWentToSleep && !mLockScreenShown) {
7204 if (mSleeping) {
7205 mSleeping = false;
7206 mMainStack.awakeFromSleepingLocked();
7207 mMainStack.resumeTopActivityLocked(null);
7208 }
7209 }
7210 }
7211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007212 public void wakingUp() {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007213 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7214 != PackageManager.PERMISSION_GRANTED) {
7215 throw new SecurityException("Requires permission "
7216 + android.Manifest.permission.DEVICE_POWER);
7217 }
7218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007219 synchronized(this) {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007220 mWentToSleep = false;
Jeff Brownc042ee22012-05-08 13:03:42 -07007221 updateEventDispatchingLocked();
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007222 comeOutOfSleepIfNeededLocked();
7223 }
7224 }
7225
Jeff Brownc042ee22012-05-08 13:03:42 -07007226 private void updateEventDispatchingLocked() {
7227 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7228 }
7229
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007230 public void setLockScreenShown(boolean shown) {
7231 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7232 != PackageManager.PERMISSION_GRANTED) {
7233 throw new SecurityException("Requires permission "
7234 + android.Manifest.permission.DEVICE_POWER);
7235 }
7236
7237 synchronized(this) {
7238 mLockScreenShown = shown;
7239 comeOutOfSleepIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007240 }
7241 }
7242
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007243 public void stopAppSwitches() {
7244 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7245 != PackageManager.PERMISSION_GRANTED) {
7246 throw new SecurityException("Requires permission "
7247 + android.Manifest.permission.STOP_APP_SWITCHES);
7248 }
7249
7250 synchronized(this) {
7251 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7252 + APP_SWITCH_DELAY_TIME;
7253 mDidAppSwitch = false;
7254 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7255 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7256 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7257 }
7258 }
7259
7260 public void resumeAppSwitches() {
7261 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7262 != PackageManager.PERMISSION_GRANTED) {
7263 throw new SecurityException("Requires permission "
7264 + android.Manifest.permission.STOP_APP_SWITCHES);
7265 }
7266
7267 synchronized(this) {
7268 // Note that we don't execute any pending app switches... we will
7269 // let those wait until either the timeout, or the next start
7270 // activity request.
7271 mAppSwitchesAllowedTime = 0;
7272 }
7273 }
7274
7275 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7276 String name) {
7277 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7278 return true;
7279 }
7280
7281 final int perm = checkComponentPermission(
7282 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08007283 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007284 if (perm == PackageManager.PERMISSION_GRANTED) {
7285 return true;
7286 }
7287
Joe Onorato8a9b2202010-02-26 18:56:32 -08007288 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007289 return false;
7290 }
7291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007292 public void setDebugApp(String packageName, boolean waitForDebugger,
7293 boolean persistent) {
7294 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7295 "setDebugApp()");
7296
7297 // Note that this is not really thread safe if there are multiple
7298 // callers into it at the same time, but that's not a situation we
7299 // care about.
7300 if (persistent) {
7301 final ContentResolver resolver = mContext.getContentResolver();
Jeff Sharkey8d9a1f62012-10-18 15:38:14 -07007302 Settings.Global.putString(
7303 resolver, Settings.Global.DEBUG_APP,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007304 packageName);
Jeff Sharkey8d9a1f62012-10-18 15:38:14 -07007305 Settings.Global.putInt(
7306 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007307 waitForDebugger ? 1 : 0);
7308 }
7309
7310 synchronized (this) {
7311 if (!persistent) {
7312 mOrigDebugApp = mDebugApp;
7313 mOrigWaitForDebugger = mWaitForDebugger;
7314 }
7315 mDebugApp = packageName;
7316 mWaitForDebugger = waitForDebugger;
7317 mDebugTransient = !persistent;
7318 if (packageName != null) {
7319 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07007320 forceStopPackageLocked(packageName, -1, false, false, true, true,
7321 UserHandle.USER_ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007322 Binder.restoreCallingIdentity(origId);
7323 }
7324 }
7325 }
7326
Siva Velusamy92a8b222012-03-09 16:24:04 -08007327 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7328 synchronized (this) {
7329 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7330 if (!isDebuggable) {
7331 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7332 throw new SecurityException("Process not debuggable: " + app.packageName);
7333 }
7334 }
7335
7336 mOpenGlTraceApp = processName;
7337 }
7338 }
7339
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007340 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7341 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7342 synchronized (this) {
7343 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7344 if (!isDebuggable) {
7345 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7346 throw new SecurityException("Process not debuggable: " + app.packageName);
7347 }
7348 }
7349 mProfileApp = processName;
7350 mProfileFile = profileFile;
7351 if (mProfileFd != null) {
7352 try {
7353 mProfileFd.close();
7354 } catch (IOException e) {
7355 }
7356 mProfileFd = null;
7357 }
7358 mProfileFd = profileFd;
7359 mProfileType = 0;
7360 mAutoStopProfiler = autoStopProfiler;
7361 }
7362 }
7363
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007364 public void setAlwaysFinish(boolean enabled) {
7365 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7366 "setAlwaysFinish()");
7367
Jeff Sharkey8d9a1f62012-10-18 15:38:14 -07007368 Settings.Global.putInt(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007369 mContext.getContentResolver(),
Jeff Sharkey8d9a1f62012-10-18 15:38:14 -07007370 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007371
7372 synchronized (this) {
7373 mAlwaysFinishActivities = enabled;
7374 }
7375 }
7376
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007377 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007378 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007379 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007380 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007381 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007382 }
7383 }
7384
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08007385 public boolean isUserAMonkey() {
7386 // For now the fact that there is a controller implies
7387 // we have a monkey.
7388 synchronized (this) {
7389 return mController != null;
7390 }
7391 }
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07007392
7393 public void requestBugReport() {
7394 // No permission check because this can't do anything harmful --
7395 // it will just eventually cause the user to be presented with
7396 // a UI to select where the bug report goes.
7397 SystemProperties.set("ctl.start", "bugreport");
7398 }
7399
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07007400 public long inputDispatchingTimedOut(int pid, boolean aboveSystem) {
7401 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
7402 != PackageManager.PERMISSION_GRANTED) {
7403 throw new SecurityException("Requires permission "
7404 + android.Manifest.permission.FILTER_EVENTS);
7405 }
7406
7407 ProcessRecord proc;
7408
7409 // TODO: Unify this code with ActivityRecord.keyDispatchingTimedOut().
7410 synchronized (this) {
7411 synchronized (mPidsSelfLocked) {
7412 proc = mPidsSelfLocked.get(pid);
7413 }
7414 if (proc != null) {
7415 if (proc.debugging) {
7416 return -1;
7417 }
7418
7419 if (mDidDexOpt) {
7420 // Give more time since we were dexopting.
7421 mDidDexOpt = false;
7422 return -1;
7423 }
7424
7425 if (proc.instrumentationClass != null) {
7426 Bundle info = new Bundle();
7427 info.putString("shortMsg", "keyDispatchingTimedOut");
7428 info.putString("longMsg", "Timed out while dispatching key event");
7429 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
7430 proc = null;
7431 }
7432 }
7433 }
7434
7435 if (proc != null) {
7436 appNotResponding(proc, null, null, aboveSystem, "keyDispatchingTimedOut");
7437 if (proc.instrumentationClass != null || proc.usingWrapper) {
7438 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
7439 }
7440 }
7441
7442 return KEY_DISPATCHING_TIMEOUT;
7443 }
7444
Jeff Sharkeya4620792011-05-20 15:29:23 -07007445 public void registerProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007446 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7447 "registerProcessObserver()");
7448 synchronized (this) {
7449 mProcessObservers.register(observer);
7450 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007451 }
7452
7453 public void unregisterProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007454 synchronized (this) {
7455 mProcessObservers.unregister(observer);
7456 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007457 }
7458
Daniel Sandler69a48172010-06-23 16:29:36 -04007459 public void setImmersive(IBinder token, boolean immersive) {
7460 synchronized(this) {
Christopher Tate73c2aee2012-03-15 16:27:14 -07007461 final ActivityRecord r = mMainStack.isInStackLocked(token);
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007462 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007463 throw new IllegalArgumentException();
7464 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007465 r.immersive = immersive;
Christopher Tate73c2aee2012-03-15 16:27:14 -07007466
7467 // update associated state if we're frontmost
7468 if (r == mFocusedActivity) {
7469 if (DEBUG_IMMERSIVE) {
7470 Slog.d(TAG, "Frontmost changed immersion: "+ r);
7471 }
7472 applyUpdateLockStateLocked(r);
7473 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007474 }
7475 }
7476
7477 public boolean isImmersive(IBinder token) {
7478 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007479 ActivityRecord r = mMainStack.isInStackLocked(token);
7480 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007481 throw new IllegalArgumentException();
7482 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007483 return r.immersive;
7484 }
7485 }
7486
7487 public boolean isTopActivityImmersive() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007488 enforceNotIsolatedCaller("startActivity");
Daniel Sandler69a48172010-06-23 16:29:36 -04007489 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007490 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04007491 return (r != null) ? r.immersive : false;
7492 }
7493 }
7494
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007495 public final void enterSafeMode() {
7496 synchronized(this) {
7497 // It only makes sense to do this before the system is ready
7498 // and started launching other packages.
7499 if (!mSystemReady) {
7500 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007501 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007502 } catch (RemoteException e) {
7503 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007504 }
7505 }
7506 }
7507
Jeff Brownb09abc12011-01-13 21:08:27 -08007508 public final void showSafeModeOverlay() {
7509 View v = LayoutInflater.from(mContext).inflate(
7510 com.android.internal.R.layout.safe_mode, null);
7511 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7512 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7513 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7514 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07007515 lp.gravity = Gravity.BOTTOM | Gravity.START;
Jeff Brownb09abc12011-01-13 21:08:27 -08007516 lp.format = v.getBackground().getOpacity();
7517 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7518 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
Craig Mautner5962b122012-10-05 14:45:52 -07007519 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
Jeff Brownb09abc12011-01-13 21:08:27 -08007520 ((WindowManager)mContext.getSystemService(
7521 Context.WINDOW_SERVICE)).addView(v, lp);
7522 }
7523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007524 public void noteWakeupAlarm(IIntentSender sender) {
7525 if (!(sender instanceof PendingIntentRecord)) {
7526 return;
7527 }
7528 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7529 synchronized (stats) {
7530 if (mBatteryStatsService.isOnBattery()) {
7531 mBatteryStatsService.enforceCallingPermission();
7532 PendingIntentRecord rec = (PendingIntentRecord)sender;
7533 int MY_UID = Binder.getCallingUid();
7534 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7535 BatteryStatsImpl.Uid.Pkg pkg =
7536 stats.getPackageStatsLocked(uid, rec.key.packageName);
7537 pkg.incWakeupsLocked();
7538 }
7539 }
7540 }
7541
Dianne Hackborn64825172011-03-02 21:32:58 -08007542 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007543 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007544 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007545 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007546 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007547 // XXX Note: don't acquire main activity lock here, because the window
7548 // manager calls in with its locks held.
7549
7550 boolean killed = false;
7551 synchronized (mPidsSelfLocked) {
7552 int[] types = new int[pids.length];
7553 int worstType = 0;
7554 for (int i=0; i<pids.length; i++) {
7555 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7556 if (proc != null) {
7557 int type = proc.setAdj;
7558 types[i] = type;
7559 if (type > worstType) {
7560 worstType = type;
7561 }
7562 }
7563 }
7564
Dianne Hackborn64825172011-03-02 21:32:58 -08007565 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007566 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007567 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7568 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07007569 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007570 }
Dianne Hackborn64825172011-03-02 21:32:58 -08007571
7572 // If this is not a secure call, don't let it kill processes that
7573 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007574 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7575 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08007576 }
7577
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007578 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007579 for (int i=0; i<pids.length; i++) {
7580 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7581 if (proc == null) {
7582 continue;
7583 }
7584 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007585 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007586 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07007587 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId, proc.pid,
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007588 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007589 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007590 proc.killedBackground = true;
7591 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007592 }
7593 }
7594 }
7595 return killed;
7596 }
Jeff Sharkeyb9a07012012-03-22 17:00:04 -07007597
7598 @Override
7599 public boolean killProcessesBelowForeground(String reason) {
7600 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7601 throw new SecurityException("killProcessesBelowForeground() only available to system");
7602 }
7603
7604 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7605 }
7606
7607 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7608 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7609 throw new SecurityException("killProcessesBelowAdj() only available to system");
7610 }
7611
7612 boolean killed = false;
7613 synchronized (mPidsSelfLocked) {
7614 final int size = mPidsSelfLocked.size();
7615 for (int i = 0; i < size; i++) {
7616 final int pid = mPidsSelfLocked.keyAt(i);
7617 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7618 if (proc == null) continue;
7619
7620 final int adj = proc.setAdj;
7621 if (adj > belowAdj && !proc.killedBackground) {
7622 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07007623 EventLog.writeEvent(EventLogTags.AM_KILL, proc.userId,
7624 proc.pid, proc.processName, adj, reason);
Jeff Sharkeyb9a07012012-03-22 17:00:04 -07007625 killed = true;
7626 proc.killedBackground = true;
7627 Process.killProcessQuiet(pid);
7628 }
7629 }
7630 }
7631 return killed;
7632 }
7633
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007634 public final void startRunning(String pkg, String cls, String action,
7635 String data) {
7636 synchronized(this) {
7637 if (mStartRunning) {
7638 return;
7639 }
7640 mStartRunning = true;
7641 mTopComponent = pkg != null && cls != null
7642 ? new ComponentName(pkg, cls) : null;
7643 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7644 mTopData = data;
7645 if (!mSystemReady) {
7646 return;
7647 }
7648 }
7649
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007650 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007651 }
7652
7653 private void retrieveSettings() {
7654 final ContentResolver resolver = mContext.getContentResolver();
Jeff Sharkey8d9a1f62012-10-18 15:38:14 -07007655 String debugApp = Settings.Global.getString(
7656 resolver, Settings.Global.DEBUG_APP);
7657 boolean waitForDebugger = Settings.Global.getInt(
7658 resolver, Settings.Global.WAIT_FOR_DEBUGGER, 0) != 0;
7659 boolean alwaysFinishActivities = Settings.Global.getInt(
7660 resolver, Settings.Global.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007661
7662 Configuration configuration = new Configuration();
7663 Settings.System.getConfiguration(resolver, configuration);
7664
7665 synchronized (this) {
7666 mDebugApp = mOrigDebugApp = debugApp;
7667 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7668 mAlwaysFinishActivities = alwaysFinishActivities;
7669 // This happens before any activities are started, so we can
7670 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08007671 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007672 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007673 }
7674 }
7675
7676 public boolean testIsSystemReady() {
7677 // no need to synchronize(this) just to read & return the value
7678 return mSystemReady;
7679 }
7680
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007681 private static File getCalledPreBootReceiversFile() {
7682 File dataDir = Environment.getDataDirectory();
7683 File systemDir = new File(dataDir, "system");
7684 File fname = new File(systemDir, "called_pre_boots.dat");
7685 return fname;
7686 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007687
7688 static final int LAST_DONE_VERSION = 10000;
7689
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007690 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7691 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7692 File file = getCalledPreBootReceiversFile();
7693 FileInputStream fis = null;
7694 try {
7695 fis = new FileInputStream(file);
7696 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007697 int fvers = dis.readInt();
7698 if (fvers == LAST_DONE_VERSION) {
7699 String vers = dis.readUTF();
7700 String codename = dis.readUTF();
7701 String build = dis.readUTF();
7702 if (android.os.Build.VERSION.RELEASE.equals(vers)
7703 && android.os.Build.VERSION.CODENAME.equals(codename)
7704 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7705 int num = dis.readInt();
7706 while (num > 0) {
7707 num--;
7708 String pkg = dis.readUTF();
7709 String cls = dis.readUTF();
7710 lastDoneReceivers.add(new ComponentName(pkg, cls));
7711 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007712 }
7713 }
7714 } catch (FileNotFoundException e) {
7715 } catch (IOException e) {
7716 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7717 } finally {
7718 if (fis != null) {
7719 try {
7720 fis.close();
7721 } catch (IOException e) {
7722 }
7723 }
7724 }
7725 return lastDoneReceivers;
7726 }
7727
7728 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7729 File file = getCalledPreBootReceiversFile();
7730 FileOutputStream fos = null;
7731 DataOutputStream dos = null;
7732 try {
7733 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7734 fos = new FileOutputStream(file);
7735 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007736 dos.writeInt(LAST_DONE_VERSION);
7737 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007738 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007739 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007740 dos.writeInt(list.size());
7741 for (int i=0; i<list.size(); i++) {
7742 dos.writeUTF(list.get(i).getPackageName());
7743 dos.writeUTF(list.get(i).getClassName());
7744 }
7745 } catch (IOException e) {
7746 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7747 file.delete();
7748 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07007749 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007750 if (dos != null) {
7751 try {
7752 dos.close();
7753 } catch (IOException e) {
7754 // TODO Auto-generated catch block
7755 e.printStackTrace();
7756 }
7757 }
7758 }
7759 }
7760
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007761 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007762 synchronized(this) {
7763 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007764 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007765 return;
7766 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007767
7768 // Check to see if there are any update receivers to run.
7769 if (!mDidUpdate) {
7770 if (mWaitingUpdate) {
7771 return;
7772 }
7773 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7774 List<ResolveInfo> ris = null;
7775 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007776 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Amith Yamasani483f3b02012-03-13 16:08:00 -07007777 intent, null, 0, 0);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007778 } catch (RemoteException e) {
7779 }
7780 if (ris != null) {
7781 for (int i=ris.size()-1; i>=0; i--) {
7782 if ((ris.get(i).activityInfo.applicationInfo.flags
7783 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7784 ris.remove(i);
7785 }
7786 }
7787 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07007788
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007789 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07007790
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007791 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007792 for (int i=0; i<ris.size(); i++) {
7793 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007794 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7795 if (lastDoneReceivers.contains(comp)) {
7796 ris.remove(i);
7797 i--;
7798 }
7799 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007800
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07007801 final int[] users = getUsersLocked();
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007802 for (int i=0; i<ris.size(); i++) {
7803 ActivityInfo ai = ris.get(i).activityInfo;
7804 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7805 doneReceivers.add(comp);
7806 intent.setComponent(comp);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07007807 for (int j=0; j<users.length; j++) {
7808 IIntentReceiver finisher = null;
7809 if (i == ris.size()-1 && j == users.length-1) {
7810 finisher = new IIntentReceiver.Stub() {
7811 public void performReceive(Intent intent, int resultCode,
7812 String data, Bundle extras, boolean ordered,
7813 boolean sticky, int sendingUser) {
7814 // The raw IIntentReceiver interface is called
7815 // with the AM lock held, so redispatch to
7816 // execute our code without the lock.
7817 mHandler.post(new Runnable() {
7818 public void run() {
7819 synchronized (ActivityManagerService.this) {
7820 mDidUpdate = true;
7821 }
7822 writeLastDonePreBootReceivers(doneReceivers);
7823 showBootMessage(mContext.getText(
7824 R.string.android_upgrading_complete),
7825 false);
7826 systemReady(goingCallback);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007827 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07007828 });
7829 }
7830 };
7831 }
7832 Slog.i(TAG, "Sending system update to " + intent.getComponent()
7833 + " for user " + users[j]);
7834 broadcastIntentLocked(null, null, intent, null, finisher,
7835 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
7836 users[j]);
7837 if (finisher != null) {
7838 mWaitingUpdate = true;
7839 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007840 }
7841 }
7842 }
7843 if (mWaitingUpdate) {
7844 return;
7845 }
7846 mDidUpdate = true;
7847 }
7848
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007849 mSystemReady = true;
7850 if (!mStartRunning) {
7851 return;
7852 }
7853 }
7854
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007855 ArrayList<ProcessRecord> procsToKill = null;
7856 synchronized(mPidsSelfLocked) {
7857 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7858 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7859 if (!isAllowedWhileBooting(proc.info)){
7860 if (procsToKill == null) {
7861 procsToKill = new ArrayList<ProcessRecord>();
7862 }
7863 procsToKill.add(proc);
7864 }
7865 }
7866 }
7867
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007868 synchronized(this) {
7869 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007870 for (int i=procsToKill.size()-1; i>=0; i--) {
7871 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007872 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007873 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007874 }
7875 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007876
7877 // Now that we have cleaned up any update processes, we
7878 // are ready to start launching real processes and know that
7879 // we won't trample on them any more.
7880 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007881 }
7882
Joe Onorato8a9b2202010-02-26 18:56:32 -08007883 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007884 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007885 SystemClock.uptimeMillis());
7886
7887 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007888 // Make sure we have no pre-ready processes sitting around.
7889
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007890 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7891 ResolveInfo ri = mContext.getPackageManager()
7892 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007893 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007894 CharSequence errorMsg = null;
7895 if (ri != null) {
7896 ActivityInfo ai = ri.activityInfo;
7897 ApplicationInfo app = ai.applicationInfo;
7898 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7899 mTopAction = Intent.ACTION_FACTORY_TEST;
7900 mTopData = null;
7901 mTopComponent = new ComponentName(app.packageName,
7902 ai.name);
7903 } else {
7904 errorMsg = mContext.getResources().getText(
7905 com.android.internal.R.string.factorytest_not_system);
7906 }
7907 } else {
7908 errorMsg = mContext.getResources().getText(
7909 com.android.internal.R.string.factorytest_no_action);
7910 }
7911 if (errorMsg != null) {
7912 mTopAction = null;
7913 mTopData = null;
7914 mTopComponent = null;
7915 Message msg = Message.obtain();
7916 msg.what = SHOW_FACTORY_ERROR_MSG;
7917 msg.getData().putCharSequence("msg", errorMsg);
7918 mHandler.sendMessage(msg);
7919 }
7920 }
7921 }
7922
7923 retrieveSettings();
7924
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007925 if (goingCallback != null) goingCallback.run();
7926
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007927 synchronized (this) {
7928 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7929 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007930 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007931 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007932 if (apps != null) {
7933 int N = apps.size();
7934 int i;
7935 for (i=0; i<N; i++) {
7936 ApplicationInfo info
7937 = (ApplicationInfo)apps.get(i);
7938 if (info != null &&
7939 !info.packageName.equals("android")) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007940 addAppLocked(info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007941 }
7942 }
7943 }
7944 } catch (RemoteException ex) {
7945 // pm is in same process, this will never happen.
7946 }
7947 }
7948
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007949 // Start up initial activity.
7950 mBooting = true;
7951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007952 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007953 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007954 Message msg = Message.obtain();
7955 msg.what = SHOW_UID_ERROR_MSG;
7956 mHandler.sendMessage(msg);
7957 }
7958 } catch (RemoteException e) {
7959 }
7960
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07007961 long ident = Binder.clearCallingIdentity();
7962 try {
7963 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07007964 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
7965 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07007966 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7967 broadcastIntentLocked(null, null, intent,
7968 null, null, 0, null, null, null,
7969 false, false, MY_PID, Process.SYSTEM_UID, mCurrentUserId);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07007970 intent = new Intent(Intent.ACTION_USER_STARTING);
7971 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
7972 intent.putExtra(Intent.EXTRA_USER_HANDLE, mCurrentUserId);
7973 broadcastIntentLocked(null, null, intent,
7974 null, new IIntentReceiver.Stub() {
7975 @Override
7976 public void performReceive(Intent intent, int resultCode, String data,
7977 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
7978 throws RemoteException {
7979 }
7980 }, 0, null, null,
7981 android.Manifest.permission.INTERACT_ACROSS_USERS,
Dianne Hackborn40e9f292012-11-27 19:12:23 -08007982 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07007983 } finally {
7984 Binder.restoreCallingIdentity(ident);
7985 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007986 mMainStack.resumeTopActivityLocked(null);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07007987 sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007988 }
7989 }
7990
Dan Egnorb7f03672009-12-09 16:22:32 -08007991 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007992 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007993 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007994 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007995 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007996 startAppProblemLocked(app);
7997 app.stopFreezingAllLocked();
7998 return handleAppCrashLocked(app);
7999 }
8000
Dan Egnorb7f03672009-12-09 16:22:32 -08008001 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008002 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008003 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08008004 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08008005 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
8006 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008007 startAppProblemLocked(app);
8008 app.stopFreezingAllLocked();
8009 }
8010
8011 /**
8012 * Generate a process error record, suitable for attachment to a ProcessRecord.
8013 *
8014 * @param app The ProcessRecord in which the error occurred.
8015 * @param condition Crashing, Application Not Responding, etc. Values are defined in
8016 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08008017 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008018 * @param shortMsg Short message describing the crash.
8019 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08008020 * @param stackTrace Full crash stack trace, may be null.
8021 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008022 * @return Returns a fully-formed AppErrorStateInfo record.
8023 */
8024 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08008025 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008026 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08008027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008028 report.condition = condition;
8029 report.processName = app.processName;
8030 report.pid = app.pid;
8031 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08008032 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008033 report.shortMsg = shortMsg;
8034 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08008035 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008036
8037 return report;
8038 }
8039
Dan Egnor42471dd2010-01-07 17:25:22 -08008040 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008041 synchronized (this) {
8042 app.crashing = false;
8043 app.crashingReport = null;
8044 app.notResponding = false;
8045 app.notRespondingReport = null;
8046 if (app.anrDialog == fromDialog) {
8047 app.anrDialog = null;
8048 }
8049 if (app.waitDialog == fromDialog) {
8050 app.waitDialog = null;
8051 }
8052 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08008053 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008054 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackbornb12e1352012-09-26 11:39:20 -07008055 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Dianne Hackborn8633e682010-04-22 16:03:41 -07008056 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07008057 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008058 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008059 }
8060 }
Dan Egnor42471dd2010-01-07 17:25:22 -08008061
Dan Egnorb7f03672009-12-09 16:22:32 -08008062 private boolean handleAppCrashLocked(ProcessRecord app) {
Mike Lockwood86548c42011-09-13 17:21:46 -04008063 if (mHeadless) {
8064 Log.e(TAG, "handleAppCrashLocked: " + app.processName);
8065 return false;
8066 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008067 long now = SystemClock.uptimeMillis();
8068
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008069 Long crashTime;
8070 if (!app.isolated) {
8071 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
8072 } else {
8073 crashTime = null;
8074 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07008075 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008076 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08008077 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008078 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08008079 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07008080 app.userId, app.info.processName, app.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008081 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
8082 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008083 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008084 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008085 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07008086 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
8087 null, "crashed", false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008088 }
8089 }
8090 if (!app.persistent) {
8091 // We don't want to start this process again until the user
8092 // explicitly does so... but for persistent process, we really
8093 // need to keep it running. If a persistent process is actually
8094 // repeatedly crashing, then badness for everyone.
Dianne Hackbornb12e1352012-09-26 11:39:20 -07008095 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.userId, app.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008096 app.info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008097 if (!app.isolated) {
8098 // XXX We don't have a way to mark isolated processes
8099 // as bad, since they don't have a peristent identity.
8100 mBadProcesses.put(app.info.processName, app.uid, now);
8101 mProcessCrashTimes.remove(app.info.processName, app.uid);
8102 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008103 app.bad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008104 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07008105 // Don't let services in this process be restarted and potentially
8106 // annoy the user repeatedly. Unless it is persistent, since those
8107 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08008108 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08008109 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 return false;
8111 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08008112 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008113 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008114 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Kevin Hester-Chowd87a9be2012-03-05 08:01:00 -08008115 if (r != null && r.app == app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008116 // If the top running activity is from this crashing
8117 // process, then terminate it to avoid getting in a loop.
8118 Slog.w(TAG, " Force finishing activity "
8119 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08008120 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008121 r.stack.finishActivityLocked(r, index,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07008122 Activity.RESULT_CANCELED, null, "crashed", false);
Dianne Hackborn070783f2010-12-29 16:46:28 -08008123 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008124 // stopped, to avoid a situation where one will get
8125 // re-start our crashing activity once it gets resumed again.
8126 index--;
8127 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008128 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008129 if (r.state == ActivityState.RESUMED
8130 || r.state == ActivityState.PAUSING
8131 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08008132 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008133 Slog.w(TAG, " Force finishing activity "
8134 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008135 r.stack.finishActivityLocked(r, index,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07008136 Activity.RESULT_CANCELED, null, "crashed", false);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07008137 }
8138 }
8139 }
8140 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008141 }
8142
8143 // Bump up the crash count of any services currently running in the proc.
8144 if (app.services.size() != 0) {
8145 // Any services running in the application need to be placed
8146 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07008147 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008148 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07008149 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 sr.crashCount++;
8151 }
8152 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02008153
8154 // If the crashing process is what we consider to be the "home process" and it has been
8155 // replaced by a third-party app, clear the package preferred activities from packages
8156 // with a home activity running in the process to prevent a repeatedly crashing app
8157 // from blocking the user to manually clear the list.
8158 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
8159 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
8160 Iterator it = mHomeProcess.activities.iterator();
8161 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07008162 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02008163 if (r.isHomeActivity) {
8164 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
8165 try {
8166 ActivityThread.getPackageManager()
8167 .clearPackagePreferredActivities(r.packageName);
8168 } catch (RemoteException c) {
8169 // pm is in same process, this will never happen.
8170 }
8171 }
8172 }
8173 }
8174
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008175 if (!app.isolated) {
8176 // XXX Can't keep track of crash times for isolated processes,
8177 // because they don't have a perisistent identity.
8178 mProcessCrashTimes.put(app.info.processName, app.uid, now);
8179 }
8180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008181 return true;
8182 }
8183
8184 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07008185 if (app.userId == mCurrentUserId) {
8186 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
8187 mContext, app.info.packageName, app.info.flags);
8188 } else {
8189 // If this app is not running under the current user, then we
8190 // can't give it a report button because that would require
8191 // launching the report UI under a different user.
8192 app.errorReportReceiver = null;
8193 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008194 skipCurrentReceiverLocked(app);
8195 }
8196
8197 void skipCurrentReceiverLocked(ProcessRecord app) {
Christopher Tatef46723b2012-01-26 14:19:24 -08008198 for (BroadcastQueue queue : mBroadcastQueues) {
8199 queue.skipCurrentReceiverLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008200 }
8201 }
8202
Dan Egnor60d87622009-12-16 16:32:58 -08008203 /**
8204 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
8205 * The application process will exit immediately after this call returns.
8206 * @param app object of the crashing app, null for the system server
8207 * @param crashInfo describing the exception
8208 */
8209 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008210 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008211 final String processName = app == null ? "system_server"
8212 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008213
8214 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Dianne Hackbornb12e1352012-09-26 11:39:20 -07008215 UserHandle.getUserId(Binder.getCallingUid()), processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008216 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008217 crashInfo.exceptionClassName,
8218 crashInfo.exceptionMessage,
8219 crashInfo.throwFileName,
8220 crashInfo.throwLineNumber);
8221
Jeff Sharkeya353d262011-10-28 11:12:06 -07008222 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008223
8224 crashApplication(r, crashInfo);
8225 }
8226
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008227 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008228 IBinder app,
8229 int violationMask,
8230 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008231 ProcessRecord r = findAppProcess(app, "StrictMode");
8232 if (r == null) {
8233 return;
8234 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008235
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008236 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08008237 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008238 boolean logIt = true;
8239 synchronized (mAlreadyLoggedViolatedStacks) {
8240 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
8241 logIt = false;
8242 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008243 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008244 // the relative pain numbers, without logging all
8245 // the stack traces repeatedly. We'd want to do
8246 // likewise in the client code, which also does
8247 // dup suppression, before the Binder call.
8248 } else {
8249 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
8250 mAlreadyLoggedViolatedStacks.clear();
8251 }
8252 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
8253 }
8254 }
8255 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008256 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008257 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008258 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008259
8260 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
8261 AppErrorResult result = new AppErrorResult();
8262 synchronized (this) {
8263 final long origId = Binder.clearCallingIdentity();
8264
8265 Message msg = Message.obtain();
8266 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
8267 HashMap<String, Object> data = new HashMap<String, Object>();
8268 data.put("result", result);
8269 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07008270 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008271 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008272 msg.obj = data;
8273 mHandler.sendMessage(msg);
8274
8275 Binder.restoreCallingIdentity(origId);
8276 }
8277 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07008278 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07008279 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07008280 }
8281
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008282 // Depending on the policy in effect, there could be a bunch of
8283 // these in quick succession so we try to batch these together to
8284 // minimize disk writes, number of dropbox entries, and maximize
8285 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008286 private void logStrictModeViolationToDropBox(
8287 ProcessRecord process,
8288 StrictMode.ViolationInfo info) {
8289 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008290 return;
8291 }
8292 final boolean isSystemApp = process == null ||
8293 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
8294 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008295 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008296 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8297 final DropBoxManager dbox = (DropBoxManager)
8298 mContext.getSystemService(Context.DROPBOX_SERVICE);
8299
8300 // Exit early if the dropbox isn't configured to accept this report type.
8301 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8302
8303 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008304 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008305 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8306 synchronized (sb) {
8307 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008308 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008309 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8310 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008311 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8312 if (info.violationNumThisLoop != 0) {
8313 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8314 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07008315 if (info.numAnimationsRunning != 0) {
8316 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8317 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07008318 if (info.broadcastIntentAction != null) {
8319 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8320 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008321 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008322 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008323 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08008324 if (info.numInstances != -1) {
8325 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8326 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008327 if (info.tags != null) {
8328 for (String tag : info.tags) {
8329 sb.append("Span-Tag: ").append(tag).append("\n");
8330 }
8331 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008332 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008333 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8334 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008335 }
8336 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008337
8338 // Only buffer up to ~64k. Various logging bits truncate
8339 // things at 128k.
8340 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008341 }
8342
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008343 // Flush immediately if the buffer's grown too large, or this
8344 // is a non-system app. Non-system apps are isolated with a
8345 // different tag & policy and not batched.
8346 //
8347 // Batching is useful during internal testing with
8348 // StrictMode settings turned up high. Without batching,
8349 // thousands of separate files could be created on boot.
8350 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008351 new Thread("Error dump: " + dropboxTag) {
8352 @Override
8353 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008354 String report;
8355 synchronized (sb) {
8356 report = sb.toString();
8357 sb.delete(0, sb.length());
8358 sb.trimToSize();
8359 }
8360 if (report.length() != 0) {
8361 dbox.addText(dropboxTag, report);
8362 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008363 }
8364 }.start();
8365 return;
8366 }
8367
8368 // System app batching:
8369 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008370 // An existing dropbox-writing thread is outstanding, so
8371 // we don't need to start it up. The existing thread will
8372 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008373 return;
8374 }
8375
8376 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8377 // (After this point, we shouldn't access AMS internal data structures.)
8378 new Thread("Error dump: " + dropboxTag) {
8379 @Override
8380 public void run() {
8381 // 5 second sleep to let stacks arrive and be batched together
8382 try {
8383 Thread.sleep(5000); // 5 seconds
8384 } catch (InterruptedException e) {}
8385
8386 String errorReport;
8387 synchronized (mStrictModeBuffer) {
8388 errorReport = mStrictModeBuffer.toString();
8389 if (errorReport.length() == 0) {
8390 return;
8391 }
8392 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8393 mStrictModeBuffer.trimToSize();
8394 }
8395 dbox.addText(dropboxTag, errorReport);
8396 }
8397 }.start();
8398 }
8399
Dan Egnor60d87622009-12-16 16:32:58 -08008400 /**
8401 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8402 * @param app object of the crashing app, null for the system server
8403 * @param tag reported by the caller
8404 * @param crashInfo describing the context of the error
8405 * @return true if the process should exit immediately (WTF is fatal)
8406 */
8407 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08008408 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008409 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008410 final String processName = app == null ? "system_server"
8411 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008412
Dianne Hackbornb12e1352012-09-26 11:39:20 -07008413 EventLog.writeEvent(EventLogTags.AM_WTF,
8414 UserHandle.getUserId(Binder.getCallingUid()), Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008415 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008416 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008417 tag, crashInfo.exceptionMessage);
8418
Jeff Sharkeya353d262011-10-28 11:12:06 -07008419 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008420
Dianne Hackborn1ab43772011-03-15 14:38:02 -07008421 if (r != null && r.pid != Process.myPid() &&
Jeff Brownbf6f6f92012-09-25 15:03:20 -07008422 Settings.Global.getInt(mContext.getContentResolver(),
8423 Settings.Global.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08008424 crashApplication(r, crashInfo);
8425 return true;
8426 } else {
8427 return false;
8428 }
8429 }
8430
8431 /**
8432 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8433 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8434 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08008435 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08008436 if (app == null) {
8437 return null;
8438 }
8439
8440 synchronized (this) {
8441 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8442 final int NA = apps.size();
8443 for (int ia=0; ia<NA; ia++) {
8444 ProcessRecord p = apps.valueAt(ia);
8445 if (p.thread != null && p.thread.asBinder() == app) {
8446 return p;
8447 }
8448 }
8449 }
8450
Dianne Hackborncb44d962011-03-10 17:02:27 -08008451 Slog.w(TAG, "Can't find mystery application for " + reason
8452 + " from pid=" + Binder.getCallingPid()
8453 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08008454 return null;
8455 }
8456 }
8457
8458 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008459 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8460 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08008461 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07008462 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8463 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008464 // Watchdog thread ends up invoking this function (with
8465 // a null ProcessRecord) to add the stack file to dropbox.
8466 // Do not acquire a lock on this (am) in such cases, as it
8467 // could cause a potential deadlock, if and when watchdog
8468 // is invoked due to unavailability of lock on am and it
8469 // would prevent watchdog from killing system_server.
8470 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008471 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008472 return;
8473 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07008474 // Note: ProcessRecord 'process' is guarded by the service
8475 // instance. (notably process.pkgList, which could otherwise change
8476 // concurrently during execution of this method)
8477 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008478 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08008479 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008480 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08008481 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8482 for (String pkg : process.pkgList) {
8483 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08008484 try {
Amith Yamasanif203aee2012-08-29 18:41:53 -07008485 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
Dan Egnora455d192010-03-12 08:52:28 -08008486 if (pi != null) {
8487 sb.append(" v").append(pi.versionCode);
8488 if (pi.versionName != null) {
8489 sb.append(" (").append(pi.versionName).append(")");
8490 }
8491 }
8492 } catch (RemoteException e) {
8493 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08008494 }
Dan Egnora455d192010-03-12 08:52:28 -08008495 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08008496 }
Dan Egnora455d192010-03-12 08:52:28 -08008497 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008498 }
8499
8500 private static String processClass(ProcessRecord process) {
8501 if (process == null || process.pid == MY_PID) {
8502 return "system_server";
8503 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8504 return "system_app";
8505 } else {
8506 return "data_app";
8507 }
8508 }
8509
8510 /**
8511 * Write a description of an error (crash, WTF, ANR) to the drop box.
8512 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8513 * @param process which caused the error, null means the system server
8514 * @param activity which triggered the error, null if unknown
8515 * @param parent activity related to the error, null if unknown
8516 * @param subject line related to the error, null if absent
8517 * @param report in long form describing the error, null if absent
8518 * @param logFile to include in the report, null if none
8519 * @param crashInfo giving an application stack trace, null if absent
8520 */
8521 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07008522 ProcessRecord process, String processName, ActivityRecord activity,
8523 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008524 final String report, final File logFile,
8525 final ApplicationErrorReport.CrashInfo crashInfo) {
8526 // NOTE -- this must never acquire the ActivityManagerService lock,
8527 // otherwise the watchdog may be prevented from resetting the system.
8528
8529 final String dropboxTag = processClass(process) + "_" + eventType;
8530 final DropBoxManager dbox = (DropBoxManager)
8531 mContext.getSystemService(Context.DROPBOX_SERVICE);
8532
8533 // Exit early if the dropbox isn't configured to accept this report type.
8534 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8535
8536 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07008537 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08008538 if (activity != null) {
8539 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8540 }
8541 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8542 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8543 }
8544 if (parent != null && parent != activity) {
8545 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8546 }
8547 if (subject != null) {
8548 sb.append("Subject: ").append(subject).append("\n");
8549 }
8550 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02008551 if (Debug.isDebuggerConnected()) {
8552 sb.append("Debugger: Connected\n");
8553 }
Dan Egnora455d192010-03-12 08:52:28 -08008554 sb.append("\n");
8555
8556 // Do the rest in a worker thread to avoid blocking the caller on I/O
8557 // (After this point, we shouldn't access AMS internal data structures.)
8558 Thread worker = new Thread("Error dump: " + dropboxTag) {
8559 @Override
8560 public void run() {
8561 if (report != null) {
8562 sb.append(report);
8563 }
8564 if (logFile != null) {
8565 try {
8566 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8567 } catch (IOException e) {
8568 Slog.e(TAG, "Error reading " + logFile, e);
8569 }
8570 }
8571 if (crashInfo != null && crashInfo.stackTrace != null) {
8572 sb.append(crashInfo.stackTrace);
8573 }
8574
Jeff Sharkey625239a2012-09-26 22:03:49 -07008575 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
8576 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
Dan Egnora455d192010-03-12 08:52:28 -08008577 if (lines > 0) {
8578 sb.append("\n");
8579
8580 // Merge several logcat streams, and take the last N lines
8581 InputStreamReader input = null;
8582 try {
8583 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8584 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8585 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8586
8587 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8588 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8589 input = new InputStreamReader(logcat.getInputStream());
8590
8591 int num;
8592 char[] buf = new char[8192];
8593 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8594 } catch (IOException e) {
8595 Slog.e(TAG, "Error running logcat", e);
8596 } finally {
8597 if (input != null) try { input.close(); } catch (IOException e) {}
8598 }
8599 }
8600
8601 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08008602 }
Dan Egnora455d192010-03-12 08:52:28 -08008603 };
8604
Dianne Hackborn56385cc2012-04-30 15:07:47 -07008605 if (process == null) {
8606 // If process is null, we are being called from some internal code
8607 // and may be about to die -- run this synchronously.
8608 worker.run();
Dan Egnora455d192010-03-12 08:52:28 -08008609 } else {
8610 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08008611 }
8612 }
8613
8614 /**
8615 * Bring up the "unexpected error" dialog box for a crashing app.
8616 * Deal with edge cases (intercepts from instrumented applications,
8617 * ActivityController, error intent receivers, that sort of thing).
8618 * @param r the application crashing
8619 * @param crashInfo describing the failure
8620 */
8621 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008622 long timeMillis = System.currentTimeMillis();
8623 String shortMsg = crashInfo.exceptionClassName;
8624 String longMsg = crashInfo.exceptionMessage;
8625 String stackTrace = crashInfo.stackTrace;
8626 if (shortMsg != null && longMsg != null) {
8627 longMsg = shortMsg + ": " + longMsg;
8628 } else if (shortMsg != null) {
8629 longMsg = shortMsg;
8630 }
8631
Dan Egnor60d87622009-12-16 16:32:58 -08008632 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008633 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008634 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008635 try {
8636 String name = r != null ? r.processName : null;
8637 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08008638 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08008639 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008640 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008641 + " at watcher's request");
8642 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08008643 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008644 }
8645 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008646 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008647 }
8648 }
8649
8650 final long origId = Binder.clearCallingIdentity();
8651
8652 // If this process is running instrumentation, finish it.
8653 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008654 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008655 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08008656 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8657 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008658 Bundle info = new Bundle();
8659 info.putString("shortMsg", shortMsg);
8660 info.putString("longMsg", longMsg);
8661 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8662 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008663 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008664 }
8665
Dan Egnor60d87622009-12-16 16:32:58 -08008666 // If we can't identify the process or it's already exceeded its crash quota,
8667 // quit right away without showing a crash dialog.
8668 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008669 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008670 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008671 }
8672
8673 Message msg = Message.obtain();
8674 msg.what = SHOW_ERROR_MSG;
8675 HashMap data = new HashMap();
8676 data.put("result", result);
8677 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008678 msg.obj = data;
8679 mHandler.sendMessage(msg);
8680
8681 Binder.restoreCallingIdentity(origId);
8682 }
8683
8684 int res = result.get();
8685
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008686 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008687 synchronized (this) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008688 if (r != null && !r.isolated) {
8689 // XXX Can't keep track of crash time for isolated processes,
8690 // since they don't have a persistent identity.
8691 mProcessCrashTimes.put(r.info.processName, r.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008692 SystemClock.uptimeMillis());
8693 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008694 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008695 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008696 }
8697 }
8698
8699 if (appErrorIntent != null) {
8700 try {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -07008701 mContext.startActivityAsUser(appErrorIntent, new UserHandle(r.userId));
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008702 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008703 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008704 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008705 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008706 }
Dan Egnorb7f03672009-12-09 16:22:32 -08008707
8708 Intent createAppErrorIntentLocked(ProcessRecord r,
8709 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8710 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008711 if (report == null) {
8712 return null;
8713 }
8714 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8715 result.setComponent(r.errorReportReceiver);
8716 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8717 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8718 return result;
8719 }
8720
Dan Egnorb7f03672009-12-09 16:22:32 -08008721 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8722 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008723 if (r.errorReportReceiver == null) {
8724 return null;
8725 }
8726
8727 if (!r.crashing && !r.notResponding) {
8728 return null;
8729 }
8730
Dan Egnorb7f03672009-12-09 16:22:32 -08008731 ApplicationErrorReport report = new ApplicationErrorReport();
8732 report.packageName = r.info.packageName;
8733 report.installerPackageName = r.errorReportReceiver.getPackageName();
8734 report.processName = r.processName;
8735 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01008736 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008737
Dan Egnorb7f03672009-12-09 16:22:32 -08008738 if (r.crashing) {
8739 report.type = ApplicationErrorReport.TYPE_CRASH;
8740 report.crashInfo = crashInfo;
8741 } else if (r.notResponding) {
8742 report.type = ApplicationErrorReport.TYPE_ANR;
8743 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008744
Dan Egnorb7f03672009-12-09 16:22:32 -08008745 report.anrInfo.activity = r.notRespondingReport.tag;
8746 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8747 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008748 }
8749
Dan Egnorb7f03672009-12-09 16:22:32 -08008750 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008751 }
8752
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008753 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008754 enforceNotIsolatedCaller("getProcessesInErrorState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008755 // assume our apps are happy - lazy create the list
8756 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8757
Dianne Hackborn0c380492012-08-20 17:23:30 -07008758 final boolean allUsers = ActivityManager.checkUidPermission(
8759 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8760 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8761 int userId = UserHandle.getUserId(Binder.getCallingUid());
8762
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008763 synchronized (this) {
8764
8765 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008766 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8767 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn0c380492012-08-20 17:23:30 -07008768 if (!allUsers && app.userId != userId) {
8769 continue;
8770 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008771 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8772 // This one's in trouble, so we'll generate a report for it
8773 // crashes are higher priority (in case there's a crash *and* an anr)
8774 ActivityManager.ProcessErrorStateInfo report = null;
8775 if (app.crashing) {
8776 report = app.crashingReport;
8777 } else if (app.notResponding) {
8778 report = app.notRespondingReport;
8779 }
8780
8781 if (report != null) {
8782 if (errList == null) {
8783 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8784 }
8785 errList.add(report);
8786 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008787 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008788 " crashing = " + app.crashing +
8789 " notResponding = " + app.notResponding);
8790 }
8791 }
8792 }
8793 }
8794
8795 return errList;
8796 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07008797
8798 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008799 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008800 if (currApp != null) {
8801 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8802 }
8803 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008804 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8805 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008806 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8807 if (currApp != null) {
8808 currApp.lru = 0;
8809 }
8810 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008811 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008812 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8813 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8814 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8815 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8816 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8817 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8818 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8819 } else {
8820 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8821 }
8822 }
8823
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008824 private void fillInProcMemInfo(ProcessRecord app,
8825 ActivityManager.RunningAppProcessInfo outInfo) {
8826 outInfo.pid = app.pid;
8827 outInfo.uid = app.info.uid;
8828 if (mHeavyWeightProcess == app) {
8829 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8830 }
8831 if (app.persistent) {
8832 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8833 }
Dianne Hackborn0c380492012-08-20 17:23:30 -07008834 if (app.hasActivities) {
8835 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8836 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008837 outInfo.lastTrimLevel = app.trimMemoryLevel;
8838 int adj = app.curAdj;
8839 outInfo.importance = oomAdjToImportance(adj, outInfo);
8840 outInfo.importanceReasonCode = app.adjTypeCode;
8841 }
8842
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008843 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008844 enforceNotIsolatedCaller("getRunningAppProcesses");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008845 // Lazy instantiation of list
8846 List<ActivityManager.RunningAppProcessInfo> runList = null;
Dianne Hackborn0c380492012-08-20 17:23:30 -07008847 final boolean allUsers = ActivityManager.checkUidPermission(
8848 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8849 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8850 int userId = UserHandle.getUserId(Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008851 synchronized (this) {
8852 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008853 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8854 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn0c380492012-08-20 17:23:30 -07008855 if (!allUsers && app.userId != userId) {
8856 continue;
8857 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008858 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8859 // Generate process state info for running application
8860 ActivityManager.RunningAppProcessInfo currApp =
8861 new ActivityManager.RunningAppProcessInfo(app.processName,
8862 app.pid, app.getPackageList());
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008863 fillInProcMemInfo(app, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008864 if (app.adjSource instanceof ProcessRecord) {
8865 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008866 currApp.importanceReasonImportance = oomAdjToImportance(
8867 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008868 } else if (app.adjSource instanceof ActivityRecord) {
8869 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008870 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8871 }
8872 if (app.adjTarget instanceof ComponentName) {
8873 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8874 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008875 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008876 // + " lru=" + currApp.lru);
8877 if (runList == null) {
8878 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8879 }
8880 runList.add(currApp);
8881 }
8882 }
8883 }
8884 return runList;
8885 }
8886
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008887 public List<ApplicationInfo> getRunningExternalApplications() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008888 enforceNotIsolatedCaller("getRunningExternalApplications");
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008889 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8890 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8891 if (runningApps != null && runningApps.size() > 0) {
8892 Set<String> extList = new HashSet<String>();
8893 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8894 if (app.pkgList != null) {
8895 for (String pkg : app.pkgList) {
8896 extList.add(pkg);
8897 }
8898 }
8899 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008900 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008901 for (String pkg : extList) {
8902 try {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07008903 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008904 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8905 retList.add(info);
8906 }
8907 } catch (RemoteException e) {
8908 }
8909 }
8910 }
8911 return retList;
8912 }
8913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008914 @Override
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008915 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8916 enforceNotIsolatedCaller("getMyMemoryState");
8917 synchronized (this) {
8918 ProcessRecord proc;
8919 synchronized (mPidsSelfLocked) {
8920 proc = mPidsSelfLocked.get(Binder.getCallingPid());
8921 }
8922 fillInProcMemInfo(proc, outInfo);
8923 }
8924 }
8925
8926 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008927 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008928 if (checkCallingPermission(android.Manifest.permission.DUMP)
8929 != PackageManager.PERMISSION_GRANTED) {
8930 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8931 + Binder.getCallingPid()
8932 + ", uid=" + Binder.getCallingUid()
8933 + " without permission "
8934 + android.Manifest.permission.DUMP);
8935 return;
8936 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008937
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008938 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008939 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008940 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008941
8942 int opti = 0;
8943 while (opti < args.length) {
8944 String opt = args[opti];
8945 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8946 break;
8947 }
8948 opti++;
8949 if ("-a".equals(opt)) {
8950 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008951 } else if ("-c".equals(opt)) {
8952 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008953 } else if ("-h".equals(opt)) {
8954 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008955 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008956 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008957 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07008958 pw.println(" b[roadcasts] [PACKAGE_NAME] [history [-s]]: broadcast state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008959 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8960 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008961 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008962 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08008963 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008964 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008965 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008966 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008967 pw.println(" all: dump all activities");
8968 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008969 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008970 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8971 pw.println(" a partial substring in a component name, a");
8972 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008973 pw.println(" -a: include all available server state.");
8974 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008975 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008976 } else {
8977 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008978 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008979 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008980
8981 long origId = Binder.clearCallingIdentity();
8982 boolean more = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008983 // Is the caller requesting to dump a particular piece of data?
8984 if (opti < args.length) {
8985 String cmd = args[opti];
8986 opti++;
8987 if ("activities".equals(cmd) || "a".equals(cmd)) {
8988 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008989 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008990 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008991 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008992 String[] newArgs;
8993 String name;
8994 if (opti >= args.length) {
8995 name = null;
8996 newArgs = EMPTY_STRING_ARRAY;
8997 } else {
8998 name = args[opti];
8999 opti++;
9000 newArgs = new String[args.length - opti];
9001 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9002 args.length - opti);
9003 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009004 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009005 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009006 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009007 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009008 String[] newArgs;
9009 String name;
9010 if (opti >= args.length) {
9011 name = null;
9012 newArgs = EMPTY_STRING_ARRAY;
9013 } else {
9014 name = args[opti];
9015 opti++;
9016 newArgs = new String[args.length - opti];
9017 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9018 args.length - opti);
9019 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009020 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009021 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009022 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009023 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009024 String[] newArgs;
9025 String name;
9026 if (opti >= args.length) {
9027 name = null;
9028 newArgs = EMPTY_STRING_ARRAY;
9029 } else {
9030 name = args[opti];
9031 opti++;
9032 newArgs = new String[args.length - opti];
9033 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9034 args.length - opti);
9035 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009036 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009037 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009038 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009039 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
9040 synchronized (this) {
9041 dumpOomLocked(fd, pw, args, opti, true);
9042 }
Marco Nelissen18cb2872011-11-15 11:19:53 -08009043 } else if ("provider".equals(cmd)) {
9044 String[] newArgs;
9045 String name;
9046 if (opti >= args.length) {
9047 name = null;
9048 newArgs = EMPTY_STRING_ARRAY;
9049 } else {
9050 name = args[opti];
9051 opti++;
9052 newArgs = new String[args.length - opti];
9053 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9054 }
9055 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
9056 pw.println("No providers match: " + name);
9057 pw.println("Use -h for help.");
9058 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009059 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
9060 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009061 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009062 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009063 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009064 String[] newArgs;
9065 String name;
9066 if (opti >= args.length) {
9067 name = null;
9068 newArgs = EMPTY_STRING_ARRAY;
9069 } else {
9070 name = args[opti];
9071 opti++;
9072 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009073 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9074 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009075 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07009076 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009077 pw.println("No services match: " + name);
9078 pw.println("Use -h for help.");
9079 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009080 } else if ("package".equals(cmd)) {
9081 String[] newArgs;
9082 if (opti >= args.length) {
9083 pw.println("package: no package name specified");
9084 pw.println("Use -h for help.");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009085 } else {
9086 dumpPackage = args[opti];
9087 opti++;
9088 newArgs = new String[args.length - opti];
9089 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
9090 args.length - opti);
9091 args = newArgs;
9092 opti = 0;
Amith Yamasani7463ada2012-04-11 15:02:39 -07009093 more = true;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009094 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009095 } else if ("services".equals(cmd) || "s".equals(cmd)) {
9096 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07009097 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009098 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009099 } else {
9100 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009101 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
9102 pw.println("Bad activity command, or no activities match: " + cmd);
9103 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009104 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07009105 }
9106 if (!more) {
9107 Binder.restoreCallingIdentity(origId);
Dianne Hackborn30d71892010-12-11 10:37:55 -08009108 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009109 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009110 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07009111
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009112 // No piece of data specified, dump everything.
9113 synchronized (this) {
9114 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009115 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009116 if (needSep) {
9117 pw.println(" ");
9118 }
9119 if (dumpAll) {
9120 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009121 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009122 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009123 if (needSep) {
9124 pw.println(" ");
9125 }
9126 if (dumpAll) {
9127 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009128 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009129 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009130 if (needSep) {
9131 pw.println(" ");
9132 }
9133 if (dumpAll) {
9134 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009135 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07009136 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009137 if (needSep) {
9138 pw.println(" ");
9139 }
9140 if (dumpAll) {
9141 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009142 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009143 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009144 if (needSep) {
9145 pw.println(" ");
9146 }
9147 if (dumpAll) {
9148 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009149 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009150 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009151 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07009152 Binder.restoreCallingIdentity(origId);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009153 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07009154
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009155 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009156 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009157 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
9158 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009159 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
9160 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009161 pw.println(" ");
9162 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009163 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
9164 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009165 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009166 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009167 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009168 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009169 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009170 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009171 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009172 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009173 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009174 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009175 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009176 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009177 if (mMainStack.mGoingToSleepActivities.size() > 0) {
9178 pw.println(" ");
9179 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009180 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009181 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08009182 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009183 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009184 pw.println(" ");
9185 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009186 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009187 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009188 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009189
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009190 pw.println(" ");
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08009191 if (mMainStack.mPausingActivity != null) {
9192 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009193 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009194 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009195 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009196 if (dumpAll) {
9197 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
9198 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009199 pw.println(" mDismissKeyguardOnNextActivity: "
9200 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009201 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009202
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009203 if (mRecentTasks.size() > 0) {
9204 pw.println();
9205 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009206
9207 final int N = mRecentTasks.size();
9208 for (int i=0; i<N; i++) {
9209 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009210 if (dumpPackage != null) {
9211 if (tr.realActivity == null ||
9212 !dumpPackage.equals(tr.realActivity)) {
9213 continue;
9214 }
9215 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009216 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
9217 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009218 if (dumpAll) {
9219 mRecentTasks.get(i).dump(pw, " ");
9220 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009221 }
9222 }
9223
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009224 if (dumpAll) {
9225 pw.println(" ");
9226 pw.println(" mCurTask: " + mCurTask);
9227 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009228
9229 return true;
9230 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009231
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009232 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009233 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009234 boolean needSep = false;
9235 int numPers = 0;
9236
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009237 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
9238
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009239 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009240 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
9241 final int NA = procs.size();
9242 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009243 ProcessRecord r = procs.valueAt(ia);
9244 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9245 continue;
9246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247 if (!needSep) {
9248 pw.println(" All known processes:");
9249 needSep = true;
9250 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009251 pw.print(r.persistent ? " *PERS*" : " *APP*");
9252 pw.print(" UID "); pw.print(procs.keyAt(ia));
9253 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009254 r.dump(pw, " ");
9255 if (r.persistent) {
9256 numPers++;
9257 }
9258 }
9259 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009260 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08009261
9262 if (mIsolatedProcesses.size() > 0) {
9263 if (needSep) pw.println(" ");
9264 needSep = true;
9265 pw.println(" Isolated process list (sorted by uid):");
9266 for (int i=0; i<mIsolatedProcesses.size(); i++) {
9267 ProcessRecord r = mIsolatedProcesses.valueAt(i);
9268 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9269 continue;
9270 }
9271 pw.println(String.format("%sIsolated #%2d: %s",
9272 " ", i, r.toString()));
9273 }
9274 }
9275
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009276 if (mLruProcesses.size() > 0) {
9277 if (needSep) pw.println(" ");
9278 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07009279 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009280 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009281 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009282 needSep = true;
9283 }
9284
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009285 if (dumpAll) {
9286 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009287 boolean printed = false;
9288 for (int i=0; i<mPidsSelfLocked.size(); i++) {
9289 ProcessRecord r = mPidsSelfLocked.valueAt(i);
9290 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9291 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009292 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009293 if (!printed) {
9294 if (needSep) pw.println(" ");
9295 needSep = true;
9296 pw.println(" PID mappings:");
9297 printed = true;
9298 }
9299 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9300 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009301 }
9302 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009303 }
9304
9305 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009306 synchronized (mPidsSelfLocked) {
9307 boolean printed = false;
9308 for (int i=0; i<mForegroundProcesses.size(); i++) {
9309 ProcessRecord r = mPidsSelfLocked.get(
9310 mForegroundProcesses.valueAt(i).pid);
9311 if (dumpPackage != null && (r == null
9312 || !dumpPackage.equals(r.info.packageName))) {
9313 continue;
9314 }
9315 if (!printed) {
9316 if (needSep) pw.println(" ");
9317 needSep = true;
9318 pw.println(" Foreground Processes:");
9319 printed = true;
9320 }
9321 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
9322 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009324 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009325 }
9326
9327 if (mPersistentStartingProcesses.size() > 0) {
9328 if (needSep) pw.println(" ");
9329 needSep = true;
9330 pw.println(" Persisent processes that are starting:");
9331 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009332 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009334
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009335 if (mRemovedProcesses.size() > 0) {
9336 if (needSep) pw.println(" ");
9337 needSep = true;
9338 pw.println(" Processes that are being removed:");
9339 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009340 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009341 }
9342
9343 if (mProcessesOnHold.size() > 0) {
9344 if (needSep) pw.println(" ");
9345 needSep = true;
9346 pw.println(" Processes that are on old until the system is ready:");
9347 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009348 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009350
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009351 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009352
9353 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009354 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009355 long now = SystemClock.uptimeMillis();
9356 for (Map.Entry<String, SparseArray<Long>> procs
9357 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009358 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009359 SparseArray<Long> uids = procs.getValue();
9360 final int N = uids.size();
9361 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009362 int puid = uids.keyAt(i);
9363 ProcessRecord r = mProcessNames.get(pname, puid);
9364 if (dumpPackage != null && (r == null
9365 || !dumpPackage.equals(r.info.packageName))) {
9366 continue;
9367 }
9368 if (!printed) {
9369 if (needSep) pw.println(" ");
9370 needSep = true;
9371 pw.println(" Time since processes crashed:");
9372 printed = true;
9373 }
9374 pw.print(" Process "); pw.print(pname);
9375 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009376 pw.print(": last crashed ");
Dianne Hackborn27ff9132012-03-06 14:57:58 -08009377 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9378 pw.println(" ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009379 }
9380 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009382
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009383 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009384 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009385 for (Map.Entry<String, SparseArray<Long>> procs
9386 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009387 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009388 SparseArray<Long> uids = procs.getValue();
9389 final int N = uids.size();
9390 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009391 int puid = uids.keyAt(i);
9392 ProcessRecord r = mProcessNames.get(pname, puid);
9393 if (dumpPackage != null && (r == null
9394 || !dumpPackage.equals(r.info.packageName))) {
9395 continue;
9396 }
9397 if (!printed) {
9398 if (needSep) pw.println(" ");
9399 needSep = true;
9400 pw.println(" Bad processes:");
9401 }
9402 pw.print(" Bad process "); pw.print(pname);
9403 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009404 pw.print(": crashed at time ");
9405 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009406 }
9407 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009409
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009410 pw.println();
Dianne Hackborn80a4af22012-08-27 19:18:31 -07009411 pw.println(" mStartedUsers:");
9412 for (int i=0; i<mStartedUsers.size(); i++) {
9413 UserStartedState uss = mStartedUsers.valueAt(i);
9414 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07009415 pw.print(": "); uss.dump("", pw);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07009416 }
Dianne Hackborna8a9bd62012-10-09 15:36:59 -07009417 pw.print(" mStartedUserArray: [");
9418 for (int i=0; i<mStartedUserArray.length; i++) {
9419 if (i > 0) pw.print(", ");
9420 pw.print(mStartedUserArray[i]);
9421 }
9422 pw.println("]");
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07009423 pw.print(" mUserLru: [");
9424 for (int i=0; i<mUserLru.size(); i++) {
9425 if (i > 0) pw.print(", ");
9426 pw.print(mUserLru.get(i));
9427 }
9428 pw.println("]");
Dianne Hackbornc72fc672012-09-20 13:12:03 -07009429 if (dumpAll) {
9430 pw.print(" mStartedUserArray: "); pw.println(Arrays.toString(mStartedUserArray));
9431 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009432 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009433 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08009434 if (dumpAll) {
9435 StringBuilder sb = new StringBuilder(128);
9436 sb.append(" mPreviousProcessVisibleTime: ");
9437 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9438 pw.println(sb);
9439 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07009440 if (mHeavyWeightProcess != null) {
9441 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9442 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009443 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009444 if (dumpAll) {
9445 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07009446 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009447 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009448 for (Map.Entry<String, Integer> entry
9449 : mCompatModePackages.getPackages().entrySet()) {
9450 String pkg = entry.getKey();
9451 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009452 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9453 continue;
9454 }
9455 if (!printed) {
9456 pw.println(" mScreenCompatPackages:");
9457 printed = true;
9458 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009459 pw.print(" "); pw.print(pkg); pw.print(": ");
9460 pw.print(mode); pw.println();
9461 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07009462 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009463 }
Dianne Hackbornff5b1582012-04-12 17:24:07 -07009464 if (mSleeping || mWentToSleep || mLockScreenShown) {
9465 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9466 + " mLockScreenShown " + mLockScreenShown);
9467 }
9468 if (mShuttingDown) {
9469 pw.println(" mShuttingDown=" + mShuttingDown);
9470 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009471 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9472 || mOrigWaitForDebugger) {
9473 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9474 + " mDebugTransient=" + mDebugTransient
9475 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9476 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08009477 if (mOpenGlTraceApp != null) {
9478 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
9479 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07009480 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9481 || mProfileFd != null) {
9482 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9483 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9484 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9485 + mAutoStopProfiler);
9486 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009487 if (mAlwaysFinishActivities || mController != null) {
9488 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9489 + " mController=" + mController);
9490 }
9491 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009492 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009493 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009494 + " mProcessesReady=" + mProcessesReady
9495 + " mSystemReady=" + mSystemReady);
9496 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009497 + " mBooted=" + mBooted
9498 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009499 pw.print(" mLastPowerCheckRealtime=");
9500 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9501 pw.println("");
9502 pw.print(" mLastPowerCheckUptime=");
9503 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9504 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009505 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9506 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07009507 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackbornee7621c2012-08-13 16:42:18 -07009508 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
9509 + " mNumHiddenProcs=" + mNumHiddenProcs
9510 + " mNumServiceProcs=" + mNumServiceProcs
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009511 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009513
9514 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009515 }
9516
Dianne Hackborn287952c2010-09-22 22:34:31 -07009517 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009518 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009519 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009520 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009521 long now = SystemClock.uptimeMillis();
9522 for (int i=0; i<mProcessesToGc.size(); i++) {
9523 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009524 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9525 continue;
9526 }
9527 if (!printed) {
9528 if (needSep) pw.println(" ");
9529 needSep = true;
9530 pw.println(" Processes that are waiting to GC:");
9531 printed = true;
9532 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009533 pw.print(" Process "); pw.println(proc);
9534 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9535 pw.print(", last gced=");
9536 pw.print(now-proc.lastRequestedGc);
9537 pw.print(" ms ago, last lowMem=");
9538 pw.print(now-proc.lastLowMemory);
9539 pw.println(" ms ago");
9540
9541 }
9542 }
9543 return needSep;
9544 }
9545
9546 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9547 int opti, boolean dumpAll) {
9548 boolean needSep = false;
9549
9550 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009551 if (needSep) pw.println(" ");
9552 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009553 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07009554 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009555 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009556 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9557 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9558 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9559 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9560 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009561 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009562 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009563 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009564 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009565 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009566 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009567
9568 if (needSep) pw.println(" ");
9569 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009570 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07009571 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009572 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009573 needSep = true;
9574 }
9575
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009576 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009577
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009578 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07009579 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009580 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009581 if (mHeavyWeightProcess != null) {
9582 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9583 }
9584
9585 return true;
9586 }
9587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009588 /**
9589 * There are three ways to call this:
Marco Nelissen18cb2872011-11-15 11:19:53 -08009590 * - no provider specified: dump all the providers
9591 * - a flattened component name that matched an existing provider was specified as the
9592 * first arg: dump that one provider
9593 * - the first arg isn't the flattened component name of an existing provider:
9594 * dump all providers whose component contains the first arg as a substring
9595 */
9596 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9597 int opti, boolean dumpAll) {
Marco Nelissende7408c2012-02-08 14:57:38 -08009598 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
Marco Nelissen18cb2872011-11-15 11:19:53 -08009599 }
9600
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009601 static class ItemMatcher {
9602 ArrayList<ComponentName> components;
9603 ArrayList<String> strings;
9604 ArrayList<Integer> objects;
9605 boolean all;
9606
9607 ItemMatcher() {
9608 all = true;
9609 }
9610
9611 void build(String name) {
9612 ComponentName componentName = ComponentName.unflattenFromString(name);
9613 if (componentName != null) {
9614 if (components == null) {
9615 components = new ArrayList<ComponentName>();
9616 }
9617 components.add(componentName);
9618 all = false;
9619 } else {
9620 int objectId = 0;
9621 // Not a '/' separated full component name; maybe an object ID?
9622 try {
9623 objectId = Integer.parseInt(name, 16);
9624 if (objects == null) {
9625 objects = new ArrayList<Integer>();
9626 }
9627 objects.add(objectId);
9628 all = false;
9629 } catch (RuntimeException e) {
9630 // Not an integer; just do string match.
9631 if (strings == null) {
9632 strings = new ArrayList<String>();
9633 }
9634 strings.add(name);
9635 all = false;
9636 }
9637 }
9638 }
9639
9640 int build(String[] args, int opti) {
9641 for (; opti<args.length; opti++) {
9642 String name = args[opti];
9643 if ("--".equals(name)) {
9644 return opti+1;
9645 }
9646 build(name);
9647 }
9648 return opti;
9649 }
9650
9651 boolean match(Object object, ComponentName comp) {
9652 if (all) {
9653 return true;
9654 }
9655 if (components != null) {
9656 for (int i=0; i<components.size(); i++) {
9657 if (components.get(i).equals(comp)) {
9658 return true;
9659 }
9660 }
9661 }
9662 if (objects != null) {
9663 for (int i=0; i<objects.size(); i++) {
9664 if (System.identityHashCode(object) == objects.get(i)) {
9665 return true;
9666 }
9667 }
9668 }
9669 if (strings != null) {
9670 String flat = comp.flattenToString();
9671 for (int i=0; i<strings.size(); i++) {
9672 if (flat.contains(strings.get(i))) {
9673 return true;
9674 }
9675 }
9676 }
9677 return false;
9678 }
9679 }
9680
Dianne Hackborn625ac272010-09-17 18:29:22 -07009681 /**
9682 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009683 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07009684 * - the cmd arg isn't the flattened component name of an existing activity:
9685 * dump all activity whose component contains the cmd as a substring
9686 * - A hex number of the ActivityRecord object instance.
9687 */
9688 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9689 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009690 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009691
9692 if ("all".equals(name)) {
9693 synchronized (this) {
9694 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009695 activities.add(r1);
9696 }
9697 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07009698 } else if ("top".equals(name)) {
9699 synchronized (this) {
9700 final int N = mMainStack.mHistory.size();
9701 if (N > 0) {
9702 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9703 }
9704 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009705 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009706 ItemMatcher matcher = new ItemMatcher();
9707 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009708
9709 synchronized (this) {
9710 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009711 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009712 activities.add(r1);
9713 }
9714 }
9715 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009716 }
9717
9718 if (activities.size() <= 0) {
9719 return false;
9720 }
9721
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009722 String[] newArgs = new String[args.length - opti];
9723 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9724
Dianne Hackborn30d71892010-12-11 10:37:55 -08009725 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009726 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08009727 for (int i=activities.size()-1; i>=0; i--) {
9728 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009729 if (needSep) {
9730 pw.println();
9731 }
9732 needSep = true;
9733 synchronized (this) {
9734 if (lastTask != r.task) {
9735 lastTask = r.task;
9736 pw.print("TASK "); pw.print(lastTask.affinity);
9737 pw.print(" id="); pw.println(lastTask.taskId);
9738 if (dumpAll) {
9739 lastTask.dump(pw, " ");
9740 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009741 }
9742 }
9743 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009744 }
9745 return true;
9746 }
9747
9748 /**
9749 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9750 * there is a thread associated with the activity.
9751 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08009752 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009753 final ActivityRecord r, String[] args, boolean dumpAll) {
9754 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08009755 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009756 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9757 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9758 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08009759 if (r.app != null) pw.println(r.app.pid);
9760 else pw.println("(not running)");
9761 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009762 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009763 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009764 }
9765 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009766 // flush anything that is already in the PrintWriter since the thread is going
9767 // to write to the file descriptor directly
9768 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07009769 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009770 TransferPipe tp = new TransferPipe();
9771 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009772 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9773 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009774 tp.go(fd);
9775 } finally {
9776 tp.kill();
9777 }
9778 } catch (IOException e) {
9779 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009780 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009781 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009782 }
9783 }
9784 }
9785
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009786 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009787 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009788 boolean needSep = false;
Dianne Hackborn786b4402012-08-27 15:14:02 -07009789 boolean onlyHistory = false;
9790
9791 if ("history".equals(dumpPackage)) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07009792 if (opti < args.length && "-s".equals(args[opti])) {
9793 dumpAll = false;
9794 }
Dianne Hackborn786b4402012-08-27 15:14:02 -07009795 onlyHistory = true;
9796 dumpPackage = null;
9797 }
9798
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009799 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackborn786b4402012-08-27 15:14:02 -07009800 if (!onlyHistory && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009801 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009802 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009803 Iterator it = mRegisteredReceivers.values().iterator();
9804 while (it.hasNext()) {
9805 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009806 if (dumpPackage != null && (r.app == null ||
9807 !dumpPackage.equals(r.app.info.packageName))) {
9808 continue;
9809 }
9810 if (!printed) {
9811 pw.println(" Registered Receivers:");
9812 needSep = true;
9813 printed = true;
9814 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009815 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009816 r.dump(pw, " ");
9817 }
9818 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009819
9820 if (mReceiverResolver.dump(pw, needSep ?
9821 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9822 " ", dumpPackage, false)) {
9823 needSep = true;
9824 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009825 }
Christopher Tatef46723b2012-01-26 14:19:24 -08009826
9827 for (BroadcastQueue q : mBroadcastQueues) {
9828 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009829 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009830
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009831 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009832
Dianne Hackborn786b4402012-08-27 15:14:02 -07009833 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07009834 for (int user=0; user<mStickyBroadcasts.size(); user++) {
9835 if (needSep) {
9836 pw.println();
9837 }
9838 needSep = true;
9839 pw.print(" Sticky broadcasts for user ");
9840 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9841 StringBuilder sb = new StringBuilder(128);
9842 for (Map.Entry<String, ArrayList<Intent>> ent
9843 : mStickyBroadcasts.valueAt(user).entrySet()) {
9844 pw.print(" * Sticky action "); pw.print(ent.getKey());
9845 if (dumpAll) {
9846 pw.println(":");
9847 ArrayList<Intent> intents = ent.getValue();
9848 final int N = intents.size();
9849 for (int i=0; i<N; i++) {
9850 sb.setLength(0);
9851 sb.append(" Intent: ");
9852 intents.get(i).toShortString(sb, false, true, false, false);
9853 pw.println(sb.toString());
9854 Bundle bundle = intents.get(i).getExtras();
9855 if (bundle != null) {
9856 pw.print(" ");
9857 pw.println(bundle.toString());
9858 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009859 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07009860 } else {
9861 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009862 }
9863 }
9864 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009865 }
9866
Dianne Hackborn786b4402012-08-27 15:14:02 -07009867 if (!onlyHistory && dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009868 pw.println();
Christopher Tatef46723b2012-01-26 14:19:24 -08009869 for (BroadcastQueue queue : mBroadcastQueues) {
9870 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
9871 + queue.mBroadcastsScheduled);
9872 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009873 pw.println(" mHandler:");
9874 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009875 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009876 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009877
9878 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009879 }
9880
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009881 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009882 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07009883 boolean needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009884
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009885 ItemMatcher matcher = new ItemMatcher();
9886 matcher.build(args, opti);
9887
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009888 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
Amith Yamasani742a6712011-05-04 14:49:28 -07009889
9890 mProviderMap.dumpProvidersLocked(pw, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009891
9892 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009893 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009894 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009895 ContentProviderRecord r = mLaunchingProviders.get(i);
9896 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9897 continue;
9898 }
9899 if (!printed) {
9900 if (needSep) pw.println(" ");
9901 needSep = true;
9902 pw.println(" Launching content providers:");
9903 printed = true;
9904 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009905 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009906 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009907 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009908 }
9909
9910 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009911 if (needSep) pw.println();
9912 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009913 pw.println("Granted Uri Permissions:");
9914 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9915 int uid = mGrantedUriPermissions.keyAt(i);
9916 HashMap<Uri, UriPermission> perms
9917 = mGrantedUriPermissions.valueAt(i);
9918 pw.print(" * UID "); pw.print(uid);
9919 pw.println(" holds:");
9920 for (UriPermission perm : perms.values()) {
9921 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009922 if (dumpAll) {
9923 perm.dump(pw, " ");
9924 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009925 }
9926 }
9927 needSep = true;
9928 }
9929
9930 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009931 }
9932
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009933 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009934 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009935 boolean needSep = false;
9936
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009937 if (mIntentSenderRecords.size() > 0) {
9938 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009939 Iterator<WeakReference<PendingIntentRecord>> it
9940 = mIntentSenderRecords.values().iterator();
9941 while (it.hasNext()) {
9942 WeakReference<PendingIntentRecord> ref = it.next();
9943 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009944 if (dumpPackage != null && (rec == null
9945 || !dumpPackage.equals(rec.key.packageName))) {
9946 continue;
9947 }
9948 if (!printed) {
9949 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9950 printed = true;
9951 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009952 needSep = true;
9953 if (rec != null) {
9954 pw.print(" * "); pw.println(rec);
9955 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009956 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009957 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009958 } else {
9959 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009960 }
9961 }
9962 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009963
9964 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009965 }
9966
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009967 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009968 String prefix, String label, boolean complete, boolean brief, boolean client,
9969 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009970 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009971 boolean needNL = false;
9972 final String innerPrefix = prefix + " ";
9973 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009974 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009975 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009976 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9977 continue;
9978 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009979 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009980 if (needNL) {
9981 pw.println(" ");
9982 needNL = false;
9983 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009984 if (lastTask != r.task) {
9985 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009986 pw.print(prefix);
9987 pw.print(full ? "* " : " ");
9988 pw.println(lastTask);
9989 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009990 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009991 } else if (complete) {
9992 // Complete + brief == give a summary. Isn't that obvious?!?
9993 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009994 pw.print(prefix); pw.print(" ");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08009995 pw.println(lastTask.intent.toInsecureStringWithClip());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009996 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009997 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009998 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009999 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
10000 pw.print(" #"); pw.print(i); pw.print(": ");
10001 pw.println(r);
10002 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010003 r.dump(pw, innerPrefix);
10004 } else if (complete) {
10005 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -070010006 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010007 if (r.app != null) {
10008 pw.print(innerPrefix); pw.println(r.app);
10009 }
10010 }
10011 if (client && r.app != null && r.app.thread != null) {
10012 // flush anything that is already in the PrintWriter since the thread is going
10013 // to write to the file descriptor directly
10014 pw.flush();
10015 try {
10016 TransferPipe tp = new TransferPipe();
10017 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -080010018 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
10019 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010020 // Short timeout, since blocking here can
10021 // deadlock with the application.
10022 tp.go(fd, 2000);
10023 } finally {
10024 tp.kill();
10025 }
10026 } catch (IOException e) {
10027 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
10028 } catch (RemoteException e) {
10029 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
10030 }
10031 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010032 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010033 }
10034 }
10035
Dianne Hackborn09c916b2009-12-08 14:50:51 -080010036 private static String buildOomTag(String prefix, String space, int val, int base) {
10037 if (val == base) {
10038 if (space == null) return prefix;
10039 return prefix + " ";
10040 }
10041 return prefix + "+" + Integer.toString(val-base);
10042 }
10043
10044 private static final int dumpProcessList(PrintWriter pw,
10045 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010046 String prefix, String normalLabel, String persistentLabel,
10047 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010048 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010049 final int N = list.size()-1;
10050 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010051 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010052 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10053 continue;
10054 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070010055 pw.println(String.format("%s%s #%2d: %s",
10056 prefix, (r.persistent ? persistentLabel : normalLabel),
10057 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010058 if (r.persistent) {
10059 numPers++;
10060 }
10061 }
10062 return numPers;
10063 }
10064
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010065 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -070010066 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -070010067 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010068 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070010069
Dianne Hackborn905577f2011-09-07 18:31:28 -070010070 ArrayList<Pair<ProcessRecord, Integer>> list
10071 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
10072 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010073 ProcessRecord r = origList.get(i);
10074 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
10075 continue;
10076 }
Dianne Hackborn905577f2011-09-07 18:31:28 -070010077 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
10078 }
10079
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010080 if (list.size() <= 0) {
10081 return false;
10082 }
10083
Dianne Hackborn905577f2011-09-07 18:31:28 -070010084 Comparator<Pair<ProcessRecord, Integer>> comparator
10085 = new Comparator<Pair<ProcessRecord, Integer>>() {
10086 @Override
10087 public int compare(Pair<ProcessRecord, Integer> object1,
10088 Pair<ProcessRecord, Integer> object2) {
10089 if (object1.first.setAdj != object2.first.setAdj) {
10090 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
10091 }
10092 if (object1.second.intValue() != object2.second.intValue()) {
10093 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
10094 }
10095 return 0;
10096 }
10097 };
10098
10099 Collections.sort(list, comparator);
10100
Dianne Hackborn287952c2010-09-22 22:34:31 -070010101 final long curRealtime = SystemClock.elapsedRealtime();
10102 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
10103 final long curUptime = SystemClock.uptimeMillis();
10104 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
10105
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010106 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -070010107 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010108 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010109 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070010110 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010111 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
10112 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010113 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
10114 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010115 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
10116 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010117 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
10118 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010119 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010120 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010121 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
10122 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
10123 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
10124 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
10125 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
10126 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
10127 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
10128 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -070010129 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
10130 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -070010131 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
10132 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010133 } else {
10134 oomAdj = Integer.toString(r.setAdj);
10135 }
10136 String schedGroup;
10137 switch (r.setSchedGroup) {
10138 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
10139 schedGroup = "B";
10140 break;
10141 case Process.THREAD_GROUP_DEFAULT:
10142 schedGroup = "F";
10143 break;
10144 default:
10145 schedGroup = Integer.toString(r.setSchedGroup);
10146 break;
10147 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010148 String foreground;
10149 if (r.foregroundActivities) {
10150 foreground = "A";
10151 } else if (r.foregroundServices) {
10152 foreground = "S";
10153 } else {
10154 foreground = " ";
10155 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070010156 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -070010157 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010158 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
10159 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -070010160 if (r.adjSource != null || r.adjTarget != null) {
10161 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010162 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070010163 if (r.adjTarget instanceof ComponentName) {
10164 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
10165 } else if (r.adjTarget != null) {
10166 pw.print(r.adjTarget.toString());
10167 } else {
10168 pw.print("{null}");
10169 }
10170 pw.print("<=");
10171 if (r.adjSource instanceof ProcessRecord) {
10172 pw.print("Proc{");
10173 pw.print(((ProcessRecord)r.adjSource).toShortString());
10174 pw.println("}");
10175 } else if (r.adjSource != null) {
10176 pw.println(r.adjSource.toString());
10177 } else {
10178 pw.println("{null}");
10179 }
10180 }
10181 if (inclDetails) {
10182 pw.print(prefix);
10183 pw.print(" ");
10184 pw.print("oom: max="); pw.print(r.maxAdj);
10185 pw.print(" hidden="); pw.print(r.hiddenAdj);
Dianne Hackbornb12e1352012-09-26 11:39:20 -070010186 pw.print(" client="); pw.print(r.clientHiddenAdj);
Dianne Hackbornee7621c2012-08-13 16:42:18 -070010187 pw.print(" empty="); pw.print(r.emptyAdj);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010188 pw.print(" curRaw="); pw.print(r.curRawAdj);
10189 pw.print(" setRaw="); pw.print(r.setRawAdj);
10190 pw.print(" cur="); pw.print(r.curAdj);
10191 pw.print(" set="); pw.println(r.setAdj);
10192 pw.print(prefix);
10193 pw.print(" ");
10194 pw.print("keeping="); pw.print(r.keeping);
10195 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010196 pw.print(" empty="); pw.print(r.empty);
10197 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -070010198
10199 if (!r.keeping) {
10200 if (r.lastWakeTime != 0) {
10201 long wtime;
10202 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
10203 synchronized (stats) {
10204 wtime = stats.getProcessWakeTime(r.info.uid,
10205 r.pid, curRealtime);
10206 }
10207 long timeUsed = wtime - r.lastWakeTime;
10208 pw.print(prefix);
10209 pw.print(" ");
10210 pw.print("keep awake over ");
10211 TimeUtils.formatDuration(realtimeSince, pw);
10212 pw.print(" used ");
10213 TimeUtils.formatDuration(timeUsed, pw);
10214 pw.print(" (");
10215 pw.print((timeUsed*100)/realtimeSince);
10216 pw.println("%)");
10217 }
10218 if (r.lastCpuTime != 0) {
10219 long timeUsed = r.curCpuTime - r.lastCpuTime;
10220 pw.print(prefix);
10221 pw.print(" ");
10222 pw.print("run cpu over ");
10223 TimeUtils.formatDuration(uptimeSince, pw);
10224 pw.print(" used ");
10225 TimeUtils.formatDuration(timeUsed, pw);
10226 pw.print(" (");
10227 pw.print((timeUsed*100)/uptimeSince);
10228 pw.println("%)");
10229 }
10230 }
10231 }
10232 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -080010233 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -070010234 }
10235
Dianne Hackbornb437e092011-08-05 17:50:29 -070010236 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010237 ArrayList<ProcessRecord> procs;
10238 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010239 if (args != null && args.length > start
10240 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010241 procs = new ArrayList<ProcessRecord>();
10242 int pid = -1;
10243 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010244 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010245 } catch (NumberFormatException e) {
10246
10247 }
10248 for (int i=mLruProcesses.size()-1; i>=0; i--) {
10249 ProcessRecord proc = mLruProcesses.get(i);
10250 if (proc.pid == pid) {
10251 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010252 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010253 procs.add(proc);
10254 }
10255 }
10256 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010257 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010258 return null;
10259 }
10260 } else {
10261 procs = new ArrayList<ProcessRecord>(mLruProcesses);
10262 }
10263 }
10264 return procs;
10265 }
10266
10267 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
10268 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010269 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010270 if (procs == null) {
10271 return;
10272 }
10273
10274 long uptime = SystemClock.uptimeMillis();
10275 long realtime = SystemClock.elapsedRealtime();
10276 pw.println("Applications Graphics Acceleration Info:");
10277 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10278
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010279 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10280 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010281 if (r.thread != null) {
10282 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
10283 pw.flush();
10284 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010285 TransferPipe tp = new TransferPipe();
10286 try {
10287 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
10288 tp.go(fd);
10289 } finally {
10290 tp.kill();
10291 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010292 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010293 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010294 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -070010295 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010296 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -070010297 pw.flush();
10298 }
10299 }
10300 }
Chet Haase9c1e23b2011-03-24 10:51:31 -070010301 }
10302
Jeff Brown6754ba22011-12-14 20:20:01 -080010303 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
10304 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
10305 if (procs == null) {
10306 return;
10307 }
10308
10309 pw.println("Applications Database Info:");
10310
10311 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10312 ProcessRecord r = procs.get(i);
10313 if (r.thread != null) {
10314 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10315 pw.flush();
10316 try {
10317 TransferPipe tp = new TransferPipe();
10318 try {
10319 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10320 tp.go(fd);
10321 } finally {
10322 tp.kill();
10323 }
10324 } catch (IOException e) {
10325 pw.println("Failure while dumping the app: " + r);
10326 pw.flush();
10327 } catch (RemoteException e) {
10328 pw.println("Got a RemoteException while dumping the app " + r);
10329 pw.flush();
10330 }
10331 }
10332 }
10333 }
10334
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010335 final static class MemItem {
10336 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010337 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010338 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010339 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010340 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010341
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010342 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010343 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010344 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010345 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010346 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010347 }
10348 }
10349
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010350 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -070010351 boolean sort) {
10352 if (sort) {
10353 Collections.sort(items, new Comparator<MemItem>() {
10354 @Override
10355 public int compare(MemItem lhs, MemItem rhs) {
10356 if (lhs.pss < rhs.pss) {
10357 return 1;
10358 } else if (lhs.pss > rhs.pss) {
10359 return -1;
10360 }
10361 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010362 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010363 });
10364 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010365
10366 for (int i=0; i<items.size(); i++) {
10367 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010368 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010369 if (mi.subitems != null) {
10370 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10371 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010372 }
10373 }
10374
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010375 // These are in KB.
10376 static final long[] DUMP_MEM_BUCKETS = new long[] {
10377 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10378 120*1024, 160*1024, 200*1024,
10379 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10380 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10381 };
10382
Dianne Hackborn672342c2011-11-29 11:29:02 -080010383 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10384 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010385 int start = label.lastIndexOf('.');
10386 if (start >= 0) start++;
10387 else start = 0;
10388 int end = label.length();
10389 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10390 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10391 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10392 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010393 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010394 out.append(label, start, end);
10395 return;
10396 }
10397 }
10398 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010399 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010400 out.append(label, start, end);
10401 }
10402
10403 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10404 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10405 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10406 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10407 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10408 };
10409 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10410 "System", "Persistent", "Foreground",
10411 "Visible", "Perceptible", "Heavy Weight",
10412 "Backup", "A Services", "Home", "Previous",
10413 "B Services", "Background"
10414 };
10415
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010416 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010417 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -080010418 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010419 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010420 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010421
10422 int opti = 0;
10423 while (opti < args.length) {
10424 String opt = args[opti];
10425 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10426 break;
10427 }
10428 opti++;
10429 if ("-a".equals(opt)) {
10430 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010431 } else if ("--oom".equals(opt)) {
10432 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010433 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010434 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010435 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010436 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010437 pw.println("If [process] is specified it can be the name or ");
10438 pw.println("pid of a specific process to dump.");
10439 return;
10440 } else {
10441 pw.println("Unknown argument: " + opt + "; use -h for help");
10442 }
10443 }
10444
10445 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010446 if (procs == null) {
10447 return;
10448 }
10449
Dianne Hackborn6447ca32009-04-07 19:50:08 -070010450 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010451 long uptime = SystemClock.uptimeMillis();
10452 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -070010453
10454 if (procs.size() == 1 || isCheckinRequest) {
10455 dumpAll = true;
10456 }
10457
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010458 if (isCheckinRequest) {
10459 // short checkin version
10460 pw.println(uptime + "," + realtime);
10461 pw.flush();
10462 } else {
10463 pw.println("Applications Memory Usage (kB):");
10464 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10465 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010466
Dianne Hackbornb437e092011-08-05 17:50:29 -070010467 String[] innerArgs = new String[args.length-opti];
10468 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10469
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010470 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10471 long nativePss=0, dalvikPss=0, otherPss=0;
10472 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10473
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010474 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10475 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10476 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -070010477
10478 long totalPss = 0;
10479
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010480 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10481 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010482 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010483 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010484 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10485 pw.flush();
10486 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010487 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010488 if (dumpAll) {
10489 try {
10490 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10491 } catch (RemoteException e) {
10492 if (!isCheckinRequest) {
10493 pw.println("Got RemoteException!");
10494 pw.flush();
10495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010496 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010497 } else {
10498 mi = new Debug.MemoryInfo();
10499 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010500 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010501
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010502 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010503 long myTotalPss = mi.getTotalPss();
10504 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010505 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010506 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010507 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010508
10509 nativePss += mi.nativePss;
10510 dalvikPss += mi.dalvikPss;
10511 otherPss += mi.otherPss;
10512 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10513 long mem = mi.getOtherPss(j);
10514 miscPss[j] += mem;
10515 otherPss -= mem;
10516 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010517
10518 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010519 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10520 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010521 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010522 if (oomProcs[oomIndex] == null) {
10523 oomProcs[oomIndex] = new ArrayList<MemItem>();
10524 }
10525 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010526 break;
10527 }
10528 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010530 }
10531 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010532
10533 if (!isCheckinRequest && procs.size() > 1) {
10534 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10535
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010536 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10537 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10538 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010539 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010540 String label = Debug.MemoryInfo.getOtherLabel(j);
10541 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010542 }
10543
Dianne Hackbornb437e092011-08-05 17:50:29 -070010544 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10545 for (int j=0; j<oomPss.length; j++) {
10546 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010547 String label = DUMP_MEM_OOM_LABEL[j];
10548 MemItem item = new MemItem(label, label, oomPss[j],
10549 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010550 item.subitems = oomProcs[j];
10551 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010552 }
10553 }
10554
Dianne Hackborn672342c2011-11-29 11:29:02 -080010555 if (outTag != null || outStack != null) {
10556 if (outTag != null) {
10557 appendMemBucket(outTag, totalPss, "total", false);
10558 }
10559 if (outStack != null) {
10560 appendMemBucket(outStack, totalPss, "total", true);
10561 }
10562 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010563 for (int i=0; i<oomMems.size(); i++) {
10564 MemItem miCat = oomMems.get(i);
10565 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10566 continue;
10567 }
10568 if (miCat.id < ProcessList.SERVICE_ADJ
10569 || miCat.id == ProcessList.HOME_APP_ADJ
10570 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010571 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10572 outTag.append(" / ");
10573 }
10574 if (outStack != null) {
10575 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10576 if (firstLine) {
10577 outStack.append(":");
10578 firstLine = false;
10579 }
10580 outStack.append("\n\t at ");
10581 } else {
10582 outStack.append("$");
10583 }
10584 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010585 for (int j=0; j<miCat.subitems.size(); j++) {
10586 MemItem mi = miCat.subitems.get(j);
10587 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010588 if (outTag != null) {
10589 outTag.append(" ");
10590 }
10591 if (outStack != null) {
10592 outStack.append("$");
10593 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010594 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010595 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10596 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10597 }
10598 if (outStack != null) {
10599 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10600 }
10601 }
10602 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10603 outStack.append("(");
10604 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10605 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10606 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10607 outStack.append(":");
10608 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10609 }
10610 }
10611 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010612 }
10613 }
10614 }
10615 }
10616
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010617 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010618 pw.println();
10619 pw.println("Total PSS by process:");
10620 dumpMemItems(pw, " ", procMems, true);
10621 pw.println();
10622 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010623 pw.println("Total PSS by OOM adjustment:");
10624 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010625 if (!oomOnly) {
10626 PrintWriter out = categoryPw != null ? categoryPw : pw;
10627 out.println();
10628 out.println("Total PSS by category:");
10629 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010630 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010631 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010632 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackbornd3e677b2012-04-05 14:58:18 -070010633 final int[] SINGLE_LONG_FORMAT = new int[] {
10634 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10635 };
10636 long[] longOut = new long[1];
10637 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10638 SINGLE_LONG_FORMAT, null, longOut, null);
10639 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10640 longOut[0] = 0;
10641 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10642 SINGLE_LONG_FORMAT, null, longOut, null);
10643 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10644 longOut[0] = 0;
10645 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10646 SINGLE_LONG_FORMAT, null, longOut, null);
10647 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10648 longOut[0] = 0;
10649 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10650 SINGLE_LONG_FORMAT, null, longOut, null);
10651 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10652 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10653 pw.print(shared); pw.println(" kB");
10654 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
10655 pw.print(voltile); pw.println(" kB volatile");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010656 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010657 }
10658
10659 /**
10660 * Searches array of arguments for the specified string
10661 * @param args array of argument strings
10662 * @param value value to search for
10663 * @return true if the value is contained in the array
10664 */
10665 private static boolean scanArgs(String[] args, String value) {
10666 if (args != null) {
10667 for (String arg : args) {
10668 if (value.equals(arg)) {
10669 return true;
10670 }
10671 }
10672 }
10673 return false;
10674 }
10675
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010676 private final boolean removeDyingProviderLocked(ProcessRecord proc,
10677 ContentProviderRecord cpr, boolean always) {
10678 final boolean inLaunching = mLaunchingProviders.contains(cpr);
10679
10680 if (!inLaunching || always) {
10681 synchronized (cpr) {
10682 cpr.launchingApp = null;
10683 cpr.notifyAll();
10684 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070010685 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010686 String names[] = cpr.info.authority.split(";");
10687 for (int j = 0; j < names.length; j++) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070010688 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 }
10690 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010691
10692 for (int i=0; i<cpr.connections.size(); i++) {
10693 ContentProviderConnection conn = cpr.connections.get(i);
10694 if (conn.waiting) {
10695 // If this connection is waiting for the provider, then we don't
10696 // need to mess with its process unless we are always removing
10697 // or for some reason the provider is not currently launching.
10698 if (inLaunching && !always) {
10699 continue;
10700 }
10701 }
10702 ProcessRecord capp = conn.client;
10703 conn.dead = true;
10704 if (conn.stableCount > 0) {
10705 if (!capp.persistent && capp.thread != null
10706 && capp.pid != 0
10707 && capp.pid != MY_PID) {
10708 Slog.i(TAG, "Kill " + capp.processName
10709 + " (pid " + capp.pid + "): provider " + cpr.info.name
10710 + " in dying process " + (proc != null ? proc.processName : "??"));
Dianne Hackbornb12e1352012-09-26 11:39:20 -070010711 EventLog.writeEvent(EventLogTags.AM_KILL, capp.userId, capp.pid,
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010712 capp.processName, capp.setAdj, "dying provider "
10713 + cpr.name.toShortString());
10714 Process.killProcessQuiet(capp.pid);
10715 }
10716 } else if (capp.thread != null && conn.provider.provider != null) {
10717 try {
10718 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10719 } catch (RemoteException e) {
10720 }
10721 // In the protocol here, we don't expect the client to correctly
10722 // clean up this connection, we'll just remove it.
10723 cpr.connections.remove(i);
10724 conn.client.conProviders.remove(conn);
10725 }
10726 }
10727
10728 if (inLaunching && always) {
10729 mLaunchingProviders.remove(cpr);
10730 }
10731 return inLaunching;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010732 }
10733
10734 /**
10735 * Main code for cleaning up a process when it has gone away. This is
10736 * called both as a result of the process dying, or directly when stopping
10737 * a process when running in single process mode.
10738 */
10739 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010740 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010741 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010742 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010743 }
10744
Dianne Hackborn36124872009-10-08 16:22:03 -070010745 mProcessesToGc.remove(app);
10746
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010747 // Dismiss any open dialogs.
10748 if (app.crashDialog != null) {
10749 app.crashDialog.dismiss();
10750 app.crashDialog = null;
10751 }
10752 if (app.anrDialog != null) {
10753 app.anrDialog.dismiss();
10754 app.anrDialog = null;
10755 }
10756 if (app.waitDialog != null) {
10757 app.waitDialog.dismiss();
10758 app.waitDialog = null;
10759 }
10760
10761 app.crashing = false;
10762 app.notResponding = false;
10763
10764 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010765 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010766 app.thread = null;
10767 app.forcingToForeground = null;
10768 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010769 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010770 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010771 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010772
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010773 mServices.killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010774
10775 boolean restart = false;
10776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010777 // Remove published content providers.
10778 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010779 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010780 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010781 ContentProviderRecord cpr = it.next();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010782
10783 final boolean always = app.bad || !allowRestart;
10784 if (removeDyingProviderLocked(app, cpr, always) || always) {
10785 // We left the provider in the launching list, need to
10786 // restart it.
10787 restart = true;
10788 }
10789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010790 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010791 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010792 }
10793 app.pubProviders.clear();
10794 }
10795
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010796 // Take care of any launching providers waiting for this process.
10797 if (checkAppInLaunchingProvidersLocked(app, false)) {
10798 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010799 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010801 // Unregister from connected content providers.
10802 if (!app.conProviders.isEmpty()) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010803 for (int i=0; i<app.conProviders.size(); i++) {
10804 ContentProviderConnection conn = app.conProviders.get(i);
10805 conn.provider.connections.remove(conn);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 }
10807 app.conProviders.clear();
10808 }
10809
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010810 // At this point there may be remaining entries in mLaunchingProviders
10811 // where we were the only one waiting, so they are no longer of use.
10812 // Look for these and clean up if found.
10813 // XXX Commented out for now. Trying to figure out a way to reproduce
10814 // the actual situation to identify what is actually going on.
10815 if (false) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010816 for (int i=0; i<mLaunchingProviders.size(); i++) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010817 ContentProviderRecord cpr = (ContentProviderRecord)
10818 mLaunchingProviders.get(i);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010819 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010820 synchronized (cpr) {
10821 cpr.launchingApp = null;
10822 cpr.notifyAll();
10823 }
10824 }
10825 }
10826 }
10827
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010828 skipCurrentReceiverLocked(app);
10829
10830 // Unregister any receivers.
10831 if (app.receivers.size() > 0) {
10832 Iterator<ReceiverList> it = app.receivers.iterator();
10833 while (it.hasNext()) {
10834 removeReceiverLocked(it.next());
10835 }
10836 app.receivers.clear();
10837 }
10838
Christopher Tate181fafa2009-05-14 11:12:14 -070010839 // If the app is undergoing backup, tell the backup manager about it
10840 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -070010841 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG, "App "
10842 + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010843 try {
10844 IBackupManager bm = IBackupManager.Stub.asInterface(
10845 ServiceManager.getService(Context.BACKUP_SERVICE));
10846 bm.agentDisconnected(app.info.packageName);
10847 } catch (RemoteException e) {
10848 // can't happen; backup manager is local
10849 }
10850 }
10851
Dianne Hackborna93c2c12012-05-31 15:29:36 -070010852 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10853 ProcessChangeItem item = mPendingProcessChanges.get(i);
10854 if (item.pid == app.pid) {
10855 mPendingProcessChanges.remove(i);
10856 mAvailProcessChanges.add(item);
10857 }
10858 }
Jeff Sharkey287bd832011-05-28 19:36:26 -070010859 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010861 // If the caller is restarting this app, then leave it in its
10862 // current lists and let the caller take care of it.
10863 if (restarting) {
10864 return;
10865 }
10866
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010867 if (!app.persistent || app.isolated) {
Dianne Hackborncc5a0552012-10-01 16:32:39 -070010868 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010869 "Removing non-persistent process during cleanup: " + app);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010870 mProcessNames.remove(app.processName, app.uid);
10871 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010872 if (mHeavyWeightProcess == app) {
Dianne Hackborn41203752012-08-31 14:05:51 -070010873 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10874 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -070010875 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010876 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010877 } else if (!app.removed) {
10878 // This app is persistent, so we need to keep its record around.
10879 // If it is not already on the pending app list, add it there
10880 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010881 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10882 mPersistentStartingProcesses.add(app);
10883 restart = true;
10884 }
10885 }
Dianne Hackborncc5a0552012-10-01 16:32:39 -070010886 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(TAG,
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010887 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010888 mProcessesOnHold.remove(app);
10889
The Android Open Source Project4df24232009-03-05 14:34:35 -080010890 if (app == mHomeProcess) {
10891 mHomeProcess = null;
10892 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010893 if (app == mPreviousProcess) {
10894 mPreviousProcess = null;
10895 }
10896
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010897 if (restart && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010898 // We have components that still need to be running in the
10899 // process, so re-launch it.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010900 mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010901 startProcessLocked(app, "restart", app.processName);
10902 } else if (app.pid > 0 && app.pid != MY_PID) {
10903 // Goodbye!
10904 synchronized (mPidsSelfLocked) {
10905 mPidsSelfLocked.remove(app.pid);
10906 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10907 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010908 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010909 }
10910 }
10911
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010912 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10913 // Look through the content providers we are waiting to have launched,
10914 // and if any run in this process then either schedule a restart of
10915 // the process or kill the client waiting for it if this process has
10916 // gone bad.
10917 int NL = mLaunchingProviders.size();
10918 boolean restart = false;
10919 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010920 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010921 if (cpr.launchingApp == app) {
10922 if (!alwaysBad && !app.bad) {
10923 restart = true;
10924 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010925 removeDyingProviderLocked(app, cpr, true);
Vairavan Srinivasan4ee36492012-09-03 17:09:58 -070010926 // cpr should have been removed from mLaunchingProviders
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010927 NL = mLaunchingProviders.size();
Vairavan Srinivasan4ee36492012-09-03 17:09:58 -070010928 i--;
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010929 }
10930 }
10931 }
10932 return restart;
10933 }
10934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010935 // =========================================================
10936 // SERVICES
10937 // =========================================================
10938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010939 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10940 int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010941 enforceNotIsolatedCaller("getServices");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010942 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010943 return mServices.getRunningServiceInfoLocked(maxNum, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010944 }
10945 }
10946
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010947 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010948 enforceNotIsolatedCaller("getRunningServiceControlPanel");
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010949 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010950 return mServices.getRunningServiceControlPanelLocked(name);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010951 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010952 }
10953
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010954 public ComponentName startService(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010955 String resolvedType, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010956 enforceNotIsolatedCaller("startService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010957 // Refuse possible leaked file descriptors
10958 if (service != null && service.hasFileDescriptors() == true) {
10959 throw new IllegalArgumentException("File descriptors passed in Intent");
10960 }
10961
Amith Yamasani742a6712011-05-04 14:49:28 -070010962 if (DEBUG_SERVICE)
10963 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010964 synchronized(this) {
10965 final int callingPid = Binder.getCallingPid();
10966 final int callingUid = Binder.getCallingUid();
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010967 checkValidCaller(callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010968 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010969 ComponentName res = mServices.startServiceLocked(caller, service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010970 resolvedType, callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010971 Binder.restoreCallingIdentity(origId);
10972 return res;
10973 }
10974 }
10975
10976 ComponentName startServiceInPackage(int uid,
Dianne Hackborn41203752012-08-31 14:05:51 -070010977 Intent service, String resolvedType, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010978 synchronized(this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070010979 if (DEBUG_SERVICE)
10980 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010981 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010982 ComponentName res = mServices.startServiceLocked(null, service,
Dianne Hackborn41203752012-08-31 14:05:51 -070010983 resolvedType, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010984 Binder.restoreCallingIdentity(origId);
10985 return res;
10986 }
10987 }
10988
10989 public int stopService(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010990 String resolvedType, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010991 enforceNotIsolatedCaller("stopService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010992 // Refuse possible leaked file descriptors
10993 if (service != null && service.hasFileDescriptors() == true) {
10994 throw new IllegalArgumentException("File descriptors passed in Intent");
10995 }
10996
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010997 checkValidCaller(Binder.getCallingUid(), userId);
10998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010999 synchronized(this) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -070011000 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011001 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011002 }
11003
11004 public IBinder peekService(Intent service, String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011005 enforceNotIsolatedCaller("peekService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011006 // Refuse possible leaked file descriptors
11007 if (service != null && service.hasFileDescriptors() == true) {
11008 throw new IllegalArgumentException("File descriptors passed in Intent");
11009 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011010 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011011 return mServices.peekServiceLocked(service, resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011012 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011013 }
11014
11015 public boolean stopServiceToken(ComponentName className, IBinder token,
11016 int startId) {
11017 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011018 return mServices.stopServiceTokenLocked(className, token, startId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011020 }
11021
11022 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070011023 int id, Notification notification, boolean removeNotification) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011025 mServices.setServiceForegroundLocked(className, token, id, notification,
11026 removeNotification);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011027 }
11028 }
Amith Yamasania4a54e22012-04-16 15:44:19 -070011029
Dianne Hackborn41203752012-08-31 14:05:51 -070011030 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
11031 boolean requireFull, String name, String callerPackage) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011032 final int callingUserId = UserHandle.getUserId(callingUid);
11033 if (callingUserId != userId) {
11034 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
11035 if ((requireFull || checkComponentPermission(
11036 android.Manifest.permission.INTERACT_ACROSS_USERS,
11037 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
11038 && checkComponentPermission(
11039 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
11040 callingPid, callingUid, -1, true)
11041 != PackageManager.PERMISSION_GRANTED) {
11042 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
11043 // In this case, they would like to just execute as their
11044 // owner user instead of failing.
11045 userId = callingUserId;
11046 } else {
Dianne Hackborn41203752012-08-31 14:05:51 -070011047 StringBuilder builder = new StringBuilder(128);
11048 builder.append("Permission Denial: ");
11049 builder.append(name);
11050 if (callerPackage != null) {
11051 builder.append(" from ");
11052 builder.append(callerPackage);
11053 }
11054 builder.append(" asks to run as user ");
11055 builder.append(userId);
11056 builder.append(" but is calling from user ");
11057 builder.append(UserHandle.getUserId(callingUid));
11058 builder.append("; this requires ");
11059 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
11060 if (!requireFull) {
Dianne Hackborn74ee8652012-09-07 18:33:18 -070011061 builder.append(" or ");
Dianne Hackborn41203752012-08-31 14:05:51 -070011062 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
11063 }
11064 String msg = builder.toString();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011065 Slog.w(TAG, msg);
11066 throw new SecurityException(msg);
11067 }
11068 }
11069 }
11070 if (userId == UserHandle.USER_CURRENT
11071 || userId == UserHandle.USER_CURRENT_OR_SELF) {
Dianne Hackborn139748f2012-09-24 11:36:57 -070011072 // Note that we may be accessing this outside of a lock...
11073 // shouldn't be a big deal, if this is being called outside
11074 // of a locked context there is intrinsically a race with
11075 // the value the caller will receive and someone else changing it.
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011076 userId = mCurrentUserId;
11077 }
11078 if (!allowAll && userId < 0) {
11079 throw new IllegalArgumentException(
11080 "Call does not support special user #" + userId);
11081 }
11082 }
11083 return userId;
11084 }
11085
Dianne Hackborn7d19e022012-08-07 19:12:33 -070011086 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
11087 String className, int flags) {
Amith Yamasania4a54e22012-04-16 15:44:19 -070011088 boolean result = false;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070011089 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -070011090 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
11091 if (ActivityManager.checkUidPermission(
11092 android.Manifest.permission.INTERACT_ACROSS_USERS,
11093 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
11094 ComponentName comp = new ComponentName(aInfo.packageName, className);
11095 String msg = "Permission Denial: Component " + comp.flattenToShortString()
11096 + " requests FLAG_SINGLE_USER, but app does not hold "
11097 + android.Manifest.permission.INTERACT_ACROSS_USERS;
11098 Slog.w(TAG, msg);
11099 throw new SecurityException(msg);
11100 }
11101 result = true;
11102 }
Amith Yamasania4a54e22012-04-16 15:44:19 -070011103 } else if (componentProcessName == aInfo.packageName) {
11104 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
11105 } else if ("system".equals(componentProcessName)) {
11106 result = true;
11107 }
11108 if (DEBUG_MU) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -070011109 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
11110 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
Amith Yamasania4a54e22012-04-16 15:44:19 -070011111 }
11112 return result;
11113 }
11114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011115 public int bindService(IApplicationThread caller, IBinder token,
11116 Intent service, String resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080011117 IServiceConnection connection, int flags, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011118 enforceNotIsolatedCaller("bindService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011119 // Refuse possible leaked file descriptors
11120 if (service != null && service.hasFileDescriptors() == true) {
11121 throw new IllegalArgumentException("File descriptors passed in Intent");
11122 }
11123
11124 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011125 return mServices.bindServiceLocked(caller, token, service, resolvedType,
11126 connection, flags, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011127 }
11128 }
11129
11130 public boolean unbindService(IServiceConnection connection) {
11131 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011132 return mServices.unbindServiceLocked(connection);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011133 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011134 }
11135
11136 public void publishService(IBinder token, Intent intent, IBinder service) {
11137 // Refuse possible leaked file descriptors
11138 if (intent != null && intent.hasFileDescriptors() == true) {
11139 throw new IllegalArgumentException("File descriptors passed in Intent");
11140 }
11141
11142 synchronized(this) {
11143 if (!(token instanceof ServiceRecord)) {
11144 throw new IllegalArgumentException("Invalid service token");
11145 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011146 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011147 }
11148 }
11149
11150 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
11151 // Refuse possible leaked file descriptors
11152 if (intent != null && intent.hasFileDescriptors() == true) {
11153 throw new IllegalArgumentException("File descriptors passed in Intent");
11154 }
11155
11156 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011157 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011158 }
11159 }
11160
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070011161 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011162 synchronized(this) {
11163 if (!(token instanceof ServiceRecord)) {
11164 throw new IllegalArgumentException("Invalid service token");
11165 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -070011166 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011167 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011168 }
11169
11170 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070011171 // BACKUP AND RESTORE
11172 // =========================================================
11173
11174 // Cause the target app to be launched if necessary and its backup agent
11175 // instantiated. The backup agent will invoke backupAgentCreated() on the
11176 // activity manager to announce its creation.
11177 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Christopher Tate346acb12012-10-15 19:20:25 -070011178 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + app + " mode=" + backupMode);
11179 enforceCallingPermission("android.permission.BACKUP", "bindBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011180
11181 synchronized(this) {
11182 // !!! TODO: currently no check here that we're already bound
11183 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
11184 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11185 synchronized (stats) {
11186 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
11187 }
11188
Dianne Hackborne7f97212011-02-24 14:40:20 -080011189 // Backup agent is now in use, its package can't be stopped.
11190 try {
11191 AppGlobals.getPackageManager().setPackageStoppedState(
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070011192 app.packageName, false, UserHandle.getUserId(app.uid));
Dianne Hackborne7f97212011-02-24 14:40:20 -080011193 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080011194 } catch (IllegalArgumentException e) {
11195 Slog.w(TAG, "Failed trying to unstop package "
11196 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080011197 }
11198
Christopher Tate181fafa2009-05-14 11:12:14 -070011199 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070011200 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
11201 ? new ComponentName(app.packageName, app.backupAgentName)
11202 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070011203 // startProcessLocked() returns existing proc's record if it's already running
11204 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011205 false, 0, "backup", hostingName, false, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070011206 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011207 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070011208 return false;
11209 }
11210
11211 r.app = proc;
11212 mBackupTarget = r;
11213 mBackupAppName = app.packageName;
11214
Christopher Tate6fa95972009-06-05 18:43:55 -070011215 // Try not to kill the process during backup
11216 updateOomAdjLocked(proc);
11217
Christopher Tate181fafa2009-05-14 11:12:14 -070011218 // If the process is already attached, schedule the creation of the backup agent now.
11219 // If it is not yet live, this will be done when it attaches to the framework.
11220 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011221 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070011222 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040011223 proc.thread.scheduleCreateBackupAgent(app,
11224 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070011225 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070011226 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070011227 }
11228 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011229 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070011230 }
11231 // Invariants: at this point, the target app process exists and the application
11232 // is either already running or in the process of coming up. mBackupTarget and
11233 // mBackupAppName describe the app, so that when it binds back to the AM we
11234 // know that it's scheduled for a backup-agent operation.
11235 }
11236
11237 return true;
11238 }
11239
Christopher Tate346acb12012-10-15 19:20:25 -070011240 @Override
11241 public void clearPendingBackup() {
11242 if (DEBUG_BACKUP) Slog.v(TAG, "clearPendingBackup");
11243 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
11244
11245 synchronized (this) {
11246 mBackupTarget = null;
11247 mBackupAppName = null;
11248 }
11249 }
11250
Christopher Tate181fafa2009-05-14 11:12:14 -070011251 // A backup agent has just come up
11252 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011253 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070011254 + " = " + agent);
11255
11256 synchronized(this) {
11257 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011258 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070011259 return;
11260 }
Dianne Hackborn06740692010-09-22 22:46:21 -070011261 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011262
Dianne Hackborn06740692010-09-22 22:46:21 -070011263 long oldIdent = Binder.clearCallingIdentity();
11264 try {
11265 IBackupManager bm = IBackupManager.Stub.asInterface(
11266 ServiceManager.getService(Context.BACKUP_SERVICE));
11267 bm.agentConnected(agentPackageName, agent);
11268 } catch (RemoteException e) {
11269 // can't happen; the backup manager service is local
11270 } catch (Exception e) {
11271 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
11272 e.printStackTrace();
11273 } finally {
11274 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070011275 }
11276 }
11277
11278 // done with this agent
11279 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011280 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070011281 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011282 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070011283 return;
11284 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011285
11286 synchronized(this) {
Christopher Tate346acb12012-10-15 19:20:25 -070011287 try {
11288 if (mBackupAppName == null) {
11289 Slog.w(TAG, "Unbinding backup agent with no active backup");
11290 return;
Christopher Tatec7b31e32009-06-10 15:49:30 -070011291 }
Christopher Tate346acb12012-10-15 19:20:25 -070011292
11293 if (!mBackupAppName.equals(appInfo.packageName)) {
11294 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
11295 return;
11296 }
11297
11298 // Not backing this app up any more; reset its OOM adjustment
11299 final ProcessRecord proc = mBackupTarget.app;
11300 updateOomAdjLocked(proc);
11301
11302 // If the app crashed during backup, 'thread' will be null here
11303 if (proc.thread != null) {
11304 try {
11305 proc.thread.scheduleDestroyBackupAgent(appInfo,
11306 compatibilityInfoForPackageLocked(appInfo));
11307 } catch (Exception e) {
11308 Slog.e(TAG, "Exception when unbinding backup agent:");
11309 e.printStackTrace();
11310 }
11311 }
11312 } finally {
11313 mBackupTarget = null;
11314 mBackupAppName = null;
Christopher Tate181fafa2009-05-14 11:12:14 -070011315 }
Christopher Tate181fafa2009-05-14 11:12:14 -070011316 }
11317 }
11318 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011319 // BROADCASTS
11320 // =========================================================
11321
Josh Bartel7f208742010-02-25 11:01:44 -060011322 private final List getStickiesLocked(String action, IntentFilter filter,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011323 List cur, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011324 final ContentResolver resolver = mContext.getContentResolver();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011325 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11326 if (stickies == null) {
11327 return cur;
11328 }
11329 final ArrayList<Intent> list = stickies.get(action);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011330 if (list == null) {
11331 return cur;
11332 }
11333 int N = list.size();
11334 for (int i=0; i<N; i++) {
11335 Intent intent = list.get(i);
11336 if (filter.match(resolver, intent, true, TAG) >= 0) {
11337 if (cur == null) {
11338 cur = new ArrayList<Intent>();
11339 }
11340 cur.add(intent);
11341 }
11342 }
11343 return cur;
11344 }
11345
Christopher Tatef46723b2012-01-26 14:19:24 -080011346 boolean isPendingBroadcastProcessLocked(int pid) {
11347 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11348 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11349 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011350
Christopher Tatef46723b2012-01-26 14:19:24 -080011351 void skipPendingBroadcastLocked(int pid) {
11352 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11353 for (BroadcastQueue queue : mBroadcastQueues) {
11354 queue.skipPendingBroadcastLocked(pid);
11355 }
11356 }
11357
11358 // The app just attached; send any pending broadcasts that it should receive
11359 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11360 boolean didSomething = false;
11361 for (BroadcastQueue queue : mBroadcastQueues) {
11362 didSomething |= queue.sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011363 }
Christopher Tatef46723b2012-01-26 14:19:24 -080011364 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011365 }
11366
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011367 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
Dianne Hackborn20e80982012-08-31 19:00:44 -070011368 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011369 enforceNotIsolatedCaller("registerReceiver");
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011370 int callingUid;
Dianne Hackborn20e80982012-08-31 19:00:44 -070011371 int callingPid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011372 synchronized(this) {
11373 ProcessRecord callerApp = null;
11374 if (caller != null) {
11375 callerApp = getRecordForAppLocked(caller);
11376 if (callerApp == null) {
11377 throw new SecurityException(
11378 "Unable to find app for caller " + caller
11379 + " (pid=" + Binder.getCallingPid()
11380 + ") when registering receiver " + receiver);
11381 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011382 if (callerApp.info.uid != Process.SYSTEM_UID &&
11383 !callerApp.pkgList.contains(callerPackage)) {
11384 throw new SecurityException("Given caller package " + callerPackage
11385 + " is not running in process " + callerApp);
11386 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011387 callingUid = callerApp.info.uid;
Dianne Hackborn20e80982012-08-31 19:00:44 -070011388 callingPid = callerApp.pid;
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011389 } else {
11390 callerPackage = null;
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011391 callingUid = Binder.getCallingUid();
Dianne Hackborn20e80982012-08-31 19:00:44 -070011392 callingPid = Binder.getCallingPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011393 }
11394
Dianne Hackborn139748f2012-09-24 11:36:57 -070011395 userId = this.handleIncomingUser(callingPid, callingUid, userId,
Dianne Hackborn20e80982012-08-31 19:00:44 -070011396 true, true, "registerReceiver", callerPackage);
11397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011398 List allSticky = null;
11399
11400 // Look for any matching sticky broadcasts...
11401 Iterator actions = filter.actionsIterator();
11402 if (actions != null) {
11403 while (actions.hasNext()) {
11404 String action = (String)actions.next();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011405 allSticky = getStickiesLocked(action, filter, allSticky,
11406 UserHandle.USER_ALL);
11407 allSticky = getStickiesLocked(action, filter, allSticky,
11408 UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011409 }
11410 } else {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011411 allSticky = getStickiesLocked(null, filter, allSticky,
11412 UserHandle.USER_ALL);
11413 allSticky = getStickiesLocked(null, filter, allSticky,
11414 UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011415 }
11416
11417 // The first sticky in the list is returned directly back to
11418 // the client.
11419 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11420
Joe Onorato8a9b2202010-02-26 18:56:32 -080011421 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011422 + ": " + sticky);
11423
11424 if (receiver == null) {
11425 return sticky;
11426 }
11427
11428 ReceiverList rl
11429 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11430 if (rl == null) {
Dianne Hackborn20e80982012-08-31 19:00:44 -070011431 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11432 userId, receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011433 if (rl.app != null) {
11434 rl.app.receivers.add(rl);
11435 } else {
11436 try {
11437 receiver.asBinder().linkToDeath(rl, 0);
11438 } catch (RemoteException e) {
11439 return sticky;
11440 }
11441 rl.linkedToDeath = true;
11442 }
11443 mRegisteredReceivers.put(receiver.asBinder(), rl);
Dianne Hackborn20e80982012-08-31 19:00:44 -070011444 } else if (rl.uid != callingUid) {
11445 throw new IllegalArgumentException(
11446 "Receiver requested to register for uid " + callingUid
11447 + " was previously registered for uid " + rl.uid);
11448 } else if (rl.pid != callingPid) {
11449 throw new IllegalArgumentException(
11450 "Receiver requested to register for pid " + callingPid
11451 + " was previously registered for pid " + rl.pid);
11452 } else if (rl.userId != userId) {
11453 throw new IllegalArgumentException(
11454 "Receiver requested to register for user " + userId
11455 + " was previously registered for user " + rl.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011456 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011457 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
Dianne Hackborn20e80982012-08-31 19:00:44 -070011458 permission, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011459 rl.add(bf);
11460 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011461 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011462 }
11463 mReceiverResolver.addFilter(bf);
11464
11465 // Enqueue broadcasts for all existing stickies that match
11466 // this filter.
11467 if (allSticky != null) {
11468 ArrayList receivers = new ArrayList();
11469 receivers.add(bf);
11470
11471 int N = allSticky.size();
11472 for (int i=0; i<N; i++) {
11473 Intent intent = (Intent)allSticky.get(i);
Christopher Tatef46723b2012-01-26 14:19:24 -080011474 BroadcastQueue queue = broadcastQueueForIntent(intent);
11475 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011476 null, -1, -1, null, receivers, null, 0, null, null,
Amith Yamasani8bf06ed2012-08-27 19:30:30 -070011477 false, true, true, -1);
Christopher Tatef46723b2012-01-26 14:19:24 -080011478 queue.enqueueParallelBroadcastLocked(r);
11479 queue.scheduleBroadcastsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011480 }
11481 }
11482
11483 return sticky;
11484 }
11485 }
11486
11487 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011488 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011489
Christopher Tatef46723b2012-01-26 14:19:24 -080011490 final long origId = Binder.clearCallingIdentity();
11491 try {
11492 boolean doTrim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011493
Christopher Tatef46723b2012-01-26 14:19:24 -080011494 synchronized(this) {
11495 ReceiverList rl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011496 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
Christopher Tatef46723b2012-01-26 14:19:24 -080011497 if (rl != null) {
11498 if (rl.curBroadcast != null) {
11499 BroadcastRecord r = rl.curBroadcast;
11500 final boolean doNext = finishReceiverLocked(
11501 receiver.asBinder(), r.resultCode, r.resultData,
11502 r.resultExtras, r.resultAbort, true);
11503 if (doNext) {
11504 doTrim = true;
11505 r.queue.processNextBroadcast(false);
11506 }
11507 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011508
Christopher Tatef46723b2012-01-26 14:19:24 -080011509 if (rl.app != null) {
11510 rl.app.receivers.remove(rl);
11511 }
11512 removeReceiverLocked(rl);
11513 if (rl.linkedToDeath) {
11514 rl.linkedToDeath = false;
11515 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011517 }
11518 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011519
Christopher Tatef46723b2012-01-26 14:19:24 -080011520 // If we actually concluded any broadcasts, we might now be able
11521 // to trim the recipients' apps from our working set
11522 if (doTrim) {
11523 trimApplications();
11524 return;
11525 }
11526
11527 } finally {
11528 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011529 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011530 }
11531
11532 void removeReceiverLocked(ReceiverList rl) {
11533 mRegisteredReceivers.remove(rl.receiver.asBinder());
11534 int N = rl.size();
11535 for (int i=0; i<N; i++) {
11536 mReceiverResolver.removeFilter(rl.get(i));
11537 }
11538 }
11539
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011540 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011541 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11542 ProcessRecord r = mLruProcesses.get(i);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011543 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011544 try {
11545 r.thread.dispatchPackageBroadcast(cmd, packages);
11546 } catch (RemoteException ex) {
11547 }
11548 }
11549 }
11550 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011551
11552 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11553 int[] users) {
11554 List<ResolveInfo> receivers = null;
11555 try {
11556 HashSet<ComponentName> singleUserReceivers = null;
11557 boolean scannedFirstReceivers = false;
11558 for (int user : users) {
11559 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11560 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070011561 if (user != 0 && newReceivers != null) {
11562 // If this is not the primary user, we need to check for
11563 // any receivers that should be filtered out.
11564 for (int i=0; i<newReceivers.size(); i++) {
11565 ResolveInfo ri = newReceivers.get(i);
11566 if ((ri.activityInfo.flags&ActivityInfo.FLAG_PRIMARY_USER_ONLY) != 0) {
11567 newReceivers.remove(i);
11568 i--;
11569 }
11570 }
11571 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011572 if (newReceivers != null && newReceivers.size() == 0) {
11573 newReceivers = null;
11574 }
11575 if (receivers == null) {
11576 receivers = newReceivers;
11577 } else if (newReceivers != null) {
11578 // We need to concatenate the additional receivers
11579 // found with what we have do far. This would be easy,
11580 // but we also need to de-dup any receivers that are
11581 // singleUser.
11582 if (!scannedFirstReceivers) {
11583 // Collect any single user receivers we had already retrieved.
11584 scannedFirstReceivers = true;
11585 for (int i=0; i<receivers.size(); i++) {
11586 ResolveInfo ri = receivers.get(i);
11587 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11588 ComponentName cn = new ComponentName(
11589 ri.activityInfo.packageName, ri.activityInfo.name);
11590 if (singleUserReceivers == null) {
11591 singleUserReceivers = new HashSet<ComponentName>();
11592 }
11593 singleUserReceivers.add(cn);
11594 }
11595 }
11596 }
11597 // Add the new results to the existing results, tracking
11598 // and de-dupping single user receivers.
11599 for (int i=0; i<newReceivers.size(); i++) {
Dianne Hackborn6cbd33f2012-09-17 18:28:24 -070011600 ResolveInfo ri = newReceivers.get(i);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011601 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11602 ComponentName cn = new ComponentName(
11603 ri.activityInfo.packageName, ri.activityInfo.name);
11604 if (singleUserReceivers == null) {
11605 singleUserReceivers = new HashSet<ComponentName>();
11606 }
11607 if (!singleUserReceivers.contains(cn)) {
11608 singleUserReceivers.add(cn);
11609 receivers.add(ri);
11610 }
11611 } else {
11612 receivers.add(ri);
11613 }
11614 }
11615 }
11616 }
11617 } catch (RemoteException ex) {
11618 // pm is in same process, this will never happen.
11619 }
11620 return receivers;
11621 }
11622
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011623 private final int broadcastIntentLocked(ProcessRecord callerApp,
11624 String callerPackage, Intent intent, String resolvedType,
11625 IIntentReceiver resultTo, int resultCode, String resultData,
11626 Bundle map, String requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070011627 boolean ordered, boolean sticky, int callingPid, int callingUid,
11628 int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011629 intent = new Intent(intent);
11630
Dianne Hackborne7f97212011-02-24 14:40:20 -080011631 // By default broadcasts do not go to stopped apps.
11632 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11633
Joe Onorato8a9b2202010-02-26 18:56:32 -080011634 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011635 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
Amith Yamasani13593602012-03-22 16:16:17 -070011636 + " ordered=" + ordered + " userid=" + userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011637 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011638 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011639 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011640
Dianne Hackborn139748f2012-09-24 11:36:57 -070011641 userId = handleIncomingUser(callingPid, callingUid, userId,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011642 true, false, "broadcast", callerPackage);
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011643
Dianne Hackbornc72fc672012-09-20 13:12:03 -070011644 // Make sure that the user who is receiving this broadcast is started.
Dianne Hackborn80a4af22012-08-27 19:18:31 -070011645 // If not, we will just skip it.
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011646 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070011647 if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
11648 & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
11649 Slog.w(TAG, "Skipping broadcast of " + intent
11650 + ": user " + userId + " is stopped");
11651 return ActivityManager.BROADCAST_SUCCESS;
11652 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070011653 }
11654
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011655 /*
11656 * Prevent non-system code (defined here to be non-persistent
11657 * processes) from sending protected broadcasts.
11658 */
Dianne Hackbornc7ba7712012-09-26 23:22:59 -070011659 int callingAppId = UserHandle.getAppId(callingUid);
11660 if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
11661 || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011662 callingUid == 0) {
11663 // Always okay.
11664 } else if (callerApp == null || !callerApp.persistent) {
11665 try {
11666 if (AppGlobals.getPackageManager().isProtectedBroadcast(
11667 intent.getAction())) {
11668 String msg = "Permission Denial: not allowed to send broadcast "
11669 + intent.getAction() + " from pid="
11670 + callingPid + ", uid=" + callingUid;
11671 Slog.w(TAG, msg);
11672 throw new SecurityException(msg);
11673 }
11674 } catch (RemoteException e) {
11675 Slog.w(TAG, "Remote exception", e);
11676 return ActivityManager.BROADCAST_SUCCESS;
11677 }
11678 }
11679
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011680 // Handle special intents: if this broadcast is from the package
11681 // manager about a package being removed, we need to remove all of
11682 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011683 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011684 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011685 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11686 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011687 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011688 || uidRemoved) {
11689 if (checkComponentPermission(
11690 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011691 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011692 == PackageManager.PERMISSION_GRANTED) {
11693 if (uidRemoved) {
11694 final Bundle intentExtras = intent.getExtras();
11695 final int uid = intentExtras != null
11696 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11697 if (uid >= 0) {
11698 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11699 synchronized (bs) {
11700 bs.removeUidStatsLocked(uid);
11701 }
11702 }
11703 } else {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011704 // If resources are unavailable just force stop all
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011705 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011706 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011707 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11708 if (list != null && (list.length > 0)) {
11709 for (String pkg : list) {
Amith Yamasani483f3b02012-03-13 16:08:00 -070011710 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011711 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011712 sendPackageBroadcastLocked(
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011713 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011714 }
11715 } else {
11716 Uri data = intent.getData();
11717 String ssp;
11718 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11719 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11720 forceStopPackageLocked(ssp,
Amith Yamasani483f3b02012-03-13 16:08:00 -070011721 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11722 false, userId);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011723 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011724 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011725 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011726 new String[] {ssp}, userId);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011727 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011728 }
11729 }
11730 }
11731 } else {
11732 String msg = "Permission Denial: " + intent.getAction()
11733 + " broadcast from " + callerPackage + " (pid=" + callingPid
11734 + ", uid=" + callingUid + ")"
11735 + " requires "
11736 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011737 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011738 throw new SecurityException(msg);
11739 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011740
11741 // Special case for adding a package: by default turn on compatibility
11742 // mode.
11743 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011744 Uri data = intent.getData();
11745 String ssp;
11746 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11747 mCompatModePackages.handlePackageAddedLocked(ssp,
11748 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011749 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011750 }
11751
11752 /*
11753 * If this is the time zone changed action, queue up a message that will reset the timezone
11754 * of all currently running processes. This message will get queued up before the broadcast
11755 * happens.
11756 */
11757 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11758 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11759 }
11760
Robert Greenwalt03595d02010-11-02 14:08:23 -070011761 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11762 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11763 }
11764
Robert Greenwalt434203a2010-10-11 16:00:27 -070011765 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11766 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11767 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11768 }
11769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011770 // Add to the sticky list if requested.
11771 if (sticky) {
11772 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11773 callingPid, callingUid)
11774 != PackageManager.PERMISSION_GRANTED) {
11775 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11776 + callingPid + ", uid=" + callingUid
11777 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011778 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011779 throw new SecurityException(msg);
11780 }
11781 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011782 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011783 + " and enforce permission " + requiredPermission);
Dianne Hackborna4972e92012-03-14 10:38:05 -070011784 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011785 }
11786 if (intent.getComponent() != null) {
11787 throw new SecurityException(
11788 "Sticky broadcasts can't target a specific component");
11789 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011790 // We use userId directly here, since the "all" target is maintained
11791 // as a separate set of sticky broadcasts.
11792 if (userId != UserHandle.USER_ALL) {
11793 // But first, if this is not a broadcast to all users, then
11794 // make sure it doesn't conflict with an existing broadcast to
11795 // all users.
11796 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11797 UserHandle.USER_ALL);
11798 if (stickies != null) {
11799 ArrayList<Intent> list = stickies.get(intent.getAction());
11800 if (list != null) {
11801 int N = list.size();
11802 int i;
11803 for (i=0; i<N; i++) {
11804 if (intent.filterEquals(list.get(i))) {
11805 throw new IllegalArgumentException(
11806 "Sticky broadcast " + intent + " for user "
11807 + userId + " conflicts with existing global broadcast");
11808 }
11809 }
11810 }
11811 }
11812 }
11813 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11814 if (stickies == null) {
11815 stickies = new HashMap<String, ArrayList<Intent>>();
11816 mStickyBroadcasts.put(userId, stickies);
11817 }
11818 ArrayList<Intent> list = stickies.get(intent.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011819 if (list == null) {
11820 list = new ArrayList<Intent>();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011821 stickies.put(intent.getAction(), list);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011822 }
11823 int N = list.size();
11824 int i;
11825 for (i=0; i<N; i++) {
11826 if (intent.filterEquals(list.get(i))) {
11827 // This sticky already exists, replace it.
11828 list.set(i, new Intent(intent));
11829 break;
11830 }
11831 }
11832 if (i >= N) {
11833 list.add(new Intent(intent));
11834 }
11835 }
11836
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011837 int[] users;
11838 if (userId == UserHandle.USER_ALL) {
11839 // Caller wants broadcast to go to all started users.
Dianne Hackbornc72fc672012-09-20 13:12:03 -070011840 users = mStartedUserArray;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011841 } else {
11842 // Caller wants broadcast to go to one specific user.
Amith Yamasanie98bde02012-10-01 11:30:47 -070011843 users = new int[] {userId};
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011844 }
11845
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011846 // Figure out who all will receive this broadcast.
11847 List receivers = null;
11848 List<BroadcastFilter> registeredReceivers = null;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011849 // Need to resolve the intent to interested receivers...
11850 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11851 == 0) {
11852 receivers = collectReceiverComponents(intent, resolvedType, users);
11853 }
11854 if (intent.getComponent() == null) {
11855 registeredReceivers = mReceiverResolver.queryIntent(intent,
11856 resolvedType, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011857 }
11858
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011859 final boolean replacePending =
11860 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11861
Joe Onorato8a9b2202010-02-26 18:56:32 -080011862 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011863 + " replacePending=" + replacePending);
11864
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011865 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11866 if (!ordered && NR > 0) {
11867 // If we are not serializing this broadcast, then send the
11868 // registered receivers separately so they don't wait for the
11869 // components to be launched.
Christopher Tatef46723b2012-01-26 14:19:24 -080011870 final BroadcastQueue queue = broadcastQueueForIntent(intent);
11871 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011872 callerPackage, callingPid, callingUid, requiredPermission,
11873 registeredReceivers, resultTo, resultCode, resultData, map,
Amith Yamasani8bf06ed2012-08-27 19:30:30 -070011874 ordered, sticky, false, userId);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011875 if (DEBUG_BROADCAST) Slog.v(
Christopher Tatef46723b2012-01-26 14:19:24 -080011876 TAG, "Enqueueing parallel broadcast " + r);
11877 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011878 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080011879 queue.enqueueParallelBroadcastLocked(r);
11880 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011881 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011882 registeredReceivers = null;
11883 NR = 0;
11884 }
11885
11886 // Merge into one list.
11887 int ir = 0;
11888 if (receivers != null) {
11889 // A special case for PACKAGE_ADDED: do not allow the package
11890 // being added to see this broadcast. This prevents them from
11891 // using this as a back door to get run as soon as they are
11892 // installed. Maybe in the future we want to have a special install
11893 // broadcast or such for apps, but we'd like to deliberately make
11894 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011895 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011896 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11897 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11898 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011899 Uri data = intent.getData();
11900 if (data != null) {
11901 String pkgName = data.getSchemeSpecificPart();
11902 if (pkgName != null) {
11903 skipPackages = new String[] { pkgName };
11904 }
11905 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011906 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011907 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011908 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011909 if (skipPackages != null && (skipPackages.length > 0)) {
11910 for (String skipPackage : skipPackages) {
11911 if (skipPackage != null) {
11912 int NT = receivers.size();
11913 for (int it=0; it<NT; it++) {
11914 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11915 if (curt.activityInfo.packageName.equals(skipPackage)) {
11916 receivers.remove(it);
11917 it--;
11918 NT--;
11919 }
11920 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011921 }
11922 }
11923 }
11924
11925 int NT = receivers != null ? receivers.size() : 0;
11926 int it = 0;
11927 ResolveInfo curt = null;
11928 BroadcastFilter curr = null;
11929 while (it < NT && ir < NR) {
11930 if (curt == null) {
11931 curt = (ResolveInfo)receivers.get(it);
11932 }
11933 if (curr == null) {
11934 curr = registeredReceivers.get(ir);
11935 }
11936 if (curr.getPriority() >= curt.priority) {
11937 // Insert this broadcast record into the final list.
11938 receivers.add(it, curr);
11939 ir++;
11940 curr = null;
11941 it++;
11942 NT++;
11943 } else {
11944 // Skip to the next ResolveInfo in the final list.
11945 it++;
11946 curt = null;
11947 }
11948 }
11949 }
11950 while (ir < NR) {
11951 if (receivers == null) {
11952 receivers = new ArrayList();
11953 }
11954 receivers.add(registeredReceivers.get(ir));
11955 ir++;
11956 }
11957
11958 if ((receivers != null && receivers.size() > 0)
11959 || resultTo != null) {
Christopher Tatef46723b2012-01-26 14:19:24 -080011960 BroadcastQueue queue = broadcastQueueForIntent(intent);
11961 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011962 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011963 receivers, resultTo, resultCode, resultData, map, ordered,
Amith Yamasani8bf06ed2012-08-27 19:30:30 -070011964 sticky, false, userId);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011965 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011966 TAG, "Enqueueing ordered broadcast " + r
Christopher Tatef46723b2012-01-26 14:19:24 -080011967 + ": prev had " + queue.mOrderedBroadcasts.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011968 if (DEBUG_BROADCAST) {
11969 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011970 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011971 }
Christopher Tatef46723b2012-01-26 14:19:24 -080011972 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011973 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080011974 queue.enqueueOrderedBroadcastLocked(r);
11975 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011976 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011977 }
11978
Dianne Hackborna4972e92012-03-14 10:38:05 -070011979 return ActivityManager.BROADCAST_SUCCESS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011980 }
11981
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011982 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011983 // Refuse possible leaked file descriptors
11984 if (intent != null && intent.hasFileDescriptors() == true) {
11985 throw new IllegalArgumentException("File descriptors passed in Intent");
11986 }
11987
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011988 int flags = intent.getFlags();
11989
11990 if (!mProcessesReady) {
11991 // if the caller really truly claims to know what they're doing, go
11992 // ahead and allow the broadcast without launching any receivers
11993 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11994 intent = new Intent(intent);
11995 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11996 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11997 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11998 + " before boot completion");
11999 throw new IllegalStateException("Cannot broadcast before boot completed");
12000 }
12001 }
12002
12003 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
12004 throw new IllegalArgumentException(
12005 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
12006 }
12007
12008 return intent;
12009 }
12010
12011 public final int broadcastIntent(IApplicationThread caller,
12012 Intent intent, String resolvedType, IIntentReceiver resultTo,
12013 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070012014 String requiredPermission, boolean serialized, boolean sticky, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012015 enforceNotIsolatedCaller("broadcastIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012016 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012017 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070012018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012019 final ProcessRecord callerApp = getRecordForAppLocked(caller);
12020 final int callingPid = Binder.getCallingPid();
12021 final int callingUid = Binder.getCallingUid();
12022 final long origId = Binder.clearCallingIdentity();
12023 int res = broadcastIntentLocked(callerApp,
12024 callerApp != null ? callerApp.info.packageName : null,
12025 intent, resolvedType, resultTo,
Amith Yamasani742a6712011-05-04 14:49:28 -070012026 resultCode, resultData, map, requiredPermission, serialized, sticky,
12027 callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012028 Binder.restoreCallingIdentity(origId);
12029 return res;
12030 }
12031 }
12032
12033 int broadcastIntentInPackage(String packageName, int uid,
12034 Intent intent, String resolvedType, IIntentReceiver resultTo,
12035 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070012036 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012037 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070012038 intent = verifyBroadcastLocked(intent);
12039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012040 final long origId = Binder.clearCallingIdentity();
12041 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
12042 resultTo, resultCode, resultData, map, requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070012043 serialized, sticky, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012044 Binder.restoreCallingIdentity(origId);
12045 return res;
12046 }
12047 }
12048
Amith Yamasani742a6712011-05-04 14:49:28 -070012049 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012050 // Refuse possible leaked file descriptors
12051 if (intent != null && intent.hasFileDescriptors() == true) {
12052 throw new IllegalArgumentException("File descriptors passed in Intent");
12053 }
12054
Dianne Hackborn139748f2012-09-24 11:36:57 -070012055 userId = handleIncomingUser(Binder.getCallingPid(),
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070012056 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
12057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012058 synchronized(this) {
12059 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
12060 != PackageManager.PERMISSION_GRANTED) {
12061 String msg = "Permission Denial: unbroadcastIntent() from pid="
12062 + Binder.getCallingPid()
12063 + ", uid=" + Binder.getCallingUid()
12064 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012065 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012066 throw new SecurityException(msg);
12067 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070012068 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
12069 if (stickies != null) {
12070 ArrayList<Intent> list = stickies.get(intent.getAction());
12071 if (list != null) {
12072 int N = list.size();
12073 int i;
12074 for (i=0; i<N; i++) {
12075 if (intent.filterEquals(list.get(i))) {
12076 list.remove(i);
12077 break;
12078 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012079 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070012080 if (list.size() <= 0) {
12081 stickies.remove(intent.getAction());
12082 }
12083 }
12084 if (stickies.size() <= 0) {
12085 mStickyBroadcasts.remove(userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012086 }
12087 }
12088 }
12089 }
12090
12091 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
12092 String resultData, Bundle resultExtras, boolean resultAbort,
12093 boolean explicit) {
Christopher Tatef46723b2012-01-26 14:19:24 -080012094 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
12095 if (r == null) {
12096 Slog.w(TAG, "finishReceiver called but not found on queue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012097 return false;
12098 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012099
Christopher Tatef46723b2012-01-26 14:19:24 -080012100 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
12101 explicit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012102 }
12103
12104 public void finishReceiver(IBinder who, int resultCode, String resultData,
12105 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012106 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012107
12108 // Refuse possible leaked file descriptors
12109 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
12110 throw new IllegalArgumentException("File descriptors passed in Bundle");
12111 }
12112
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012113 final long origId = Binder.clearCallingIdentity();
Christopher Tatef46723b2012-01-26 14:19:24 -080012114 try {
12115 boolean doNext = false;
12116 BroadcastRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012117
Christopher Tatef46723b2012-01-26 14:19:24 -080012118 synchronized(this) {
12119 r = broadcastRecordForReceiverLocked(who);
12120 if (r != null) {
12121 doNext = r.queue.finishReceiverLocked(r, resultCode,
12122 resultData, resultExtras, resultAbort, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012123 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012124 }
Jeff Brown4d94a762010-09-23 11:33:28 -070012125
Christopher Tatef46723b2012-01-26 14:19:24 -080012126 if (doNext) {
12127 r.queue.processNextBroadcast(false);
12128 }
12129 trimApplications();
12130 } finally {
12131 Binder.restoreCallingIdentity(origId);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070012132 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012133 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012134
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012135 // =========================================================
12136 // INSTRUMENTATION
12137 // =========================================================
12138
12139 public boolean startInstrumentation(ComponentName className,
12140 String profileFile, int flags, Bundle arguments,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -070012141 IInstrumentationWatcher watcher, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012142 enforceNotIsolatedCaller("startInstrumentation");
Dianne Hackborn139748f2012-09-24 11:36:57 -070012143 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -070012144 userId, false, true, "startInstrumentation", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012145 // Refuse possible leaked file descriptors
12146 if (arguments != null && arguments.hasFileDescriptors()) {
12147 throw new IllegalArgumentException("File descriptors passed in Bundle");
12148 }
12149
12150 synchronized(this) {
12151 InstrumentationInfo ii = null;
12152 ApplicationInfo ai = null;
12153 try {
12154 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070012155 className, STOCK_PM_FLAGS);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -070012156 ai = AppGlobals.getPackageManager().getApplicationInfo(
12157 ii.targetPackage, STOCK_PM_FLAGS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012158 } catch (PackageManager.NameNotFoundException e) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -070012159 } catch (RemoteException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012160 }
12161 if (ii == null) {
12162 reportStartInstrumentationFailure(watcher, className,
12163 "Unable to find instrumentation info for: " + className);
12164 return false;
12165 }
12166 if (ai == null) {
12167 reportStartInstrumentationFailure(watcher, className,
12168 "Unable to find instrumentation target package: " + ii.targetPackage);
12169 return false;
12170 }
12171
12172 int match = mContext.getPackageManager().checkSignatures(
12173 ii.targetPackage, ii.packageName);
12174 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
12175 String msg = "Permission Denial: starting instrumentation "
12176 + className + " from pid="
12177 + Binder.getCallingPid()
12178 + ", uid=" + Binder.getCallingPid()
12179 + " not allowed because package " + ii.packageName
12180 + " does not have a signature matching the target "
12181 + ii.targetPackage;
12182 reportStartInstrumentationFailure(watcher, className, msg);
12183 throw new SecurityException(msg);
12184 }
12185
12186 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070012187 // Instrumentation can kill and relaunch even persistent processes
Amith Yamasani483f3b02012-03-13 16:08:00 -070012188 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080012189 ProcessRecord app = addAppLocked(ai, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012190 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012191 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012192 app.instrumentationProfileFile = profileFile;
12193 app.instrumentationArguments = arguments;
12194 app.instrumentationWatcher = watcher;
12195 app.instrumentationResultClass = className;
12196 Binder.restoreCallingIdentity(origId);
12197 }
12198
12199 return true;
12200 }
12201
12202 /**
12203 * Report errors that occur while attempting to start Instrumentation. Always writes the
12204 * error to the logs, but if somebody is watching, send the report there too. This enables
12205 * the "am" command to report errors with more information.
12206 *
12207 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
12208 * @param cn The component name of the instrumentation.
12209 * @param report The error report.
12210 */
12211 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
12212 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012213 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012214 try {
12215 if (watcher != null) {
12216 Bundle results = new Bundle();
12217 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
12218 results.putString("Error", report);
12219 watcher.instrumentationStatus(cn, -1, results);
12220 }
12221 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012222 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012223 }
12224 }
12225
12226 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
12227 if (app.instrumentationWatcher != null) {
12228 try {
12229 // NOTE: IInstrumentationWatcher *must* be oneway here
12230 app.instrumentationWatcher.instrumentationFinished(
12231 app.instrumentationClass,
12232 resultCode,
12233 results);
12234 } catch (RemoteException e) {
12235 }
12236 }
12237 app.instrumentationWatcher = null;
12238 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070012239 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012240 app.instrumentationProfileFile = null;
12241 app.instrumentationArguments = null;
12242
Dianne Hackborn80a4af22012-08-27 19:18:31 -070012243 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012244 }
12245
12246 public void finishInstrumentation(IApplicationThread target,
12247 int resultCode, Bundle results) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070012248 int userId = UserHandle.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012249 // Refuse possible leaked file descriptors
12250 if (results != null && results.hasFileDescriptors()) {
12251 throw new IllegalArgumentException("File descriptors passed in Intent");
12252 }
12253
12254 synchronized(this) {
12255 ProcessRecord app = getRecordForAppLocked(target);
12256 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012257 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012258 return;
12259 }
12260 final long origId = Binder.clearCallingIdentity();
12261 finishInstrumentationLocked(app, resultCode, results);
12262 Binder.restoreCallingIdentity(origId);
12263 }
12264 }
12265
12266 // =========================================================
12267 // CONFIGURATION
12268 // =========================================================
12269
12270 public ConfigurationInfo getDeviceConfigurationInfo() {
12271 ConfigurationInfo config = new ConfigurationInfo();
12272 synchronized (this) {
12273 config.reqTouchScreen = mConfiguration.touchscreen;
12274 config.reqKeyboardType = mConfiguration.keyboard;
12275 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012276 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
12277 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012278 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
12279 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070012280 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
12281 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012282 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
12283 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070012284 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012285 }
12286 return config;
12287 }
12288
12289 public Configuration getConfiguration() {
12290 Configuration ci;
12291 synchronized(this) {
12292 ci = new Configuration(mConfiguration);
12293 }
12294 return ci;
12295 }
12296
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012297 public void updatePersistentConfiguration(Configuration values) {
12298 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12299 "updateConfiguration()");
12300 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
12301 "updateConfiguration()");
12302 if (values == null) {
12303 throw new NullPointerException("Configuration must not be null");
12304 }
12305
12306 synchronized(this) {
12307 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080012308 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012309 Binder.restoreCallingIdentity(origId);
12310 }
12311 }
12312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012313 public void updateConfiguration(Configuration values) {
12314 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
12315 "updateConfiguration()");
12316
12317 synchronized(this) {
12318 if (values == null && mWindowManager != null) {
12319 // sentinel: fetch the current configuration from the window manager
12320 values = mWindowManager.computeNewConfiguration();
12321 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012322
12323 if (mWindowManager != null) {
12324 mProcessList.applyDisplaySize(mWindowManager);
12325 }
12326
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012327 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012328 if (values != null) {
12329 Settings.System.clearConfiguration(values);
12330 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080012331 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012332 Binder.restoreCallingIdentity(origId);
12333 }
12334 }
12335
12336 /**
12337 * Do either or both things: (1) change the current configuration, and (2)
12338 * make sure the given activity is running with the (now) current
12339 * configuration. Returns true if the activity has been left running, or
12340 * false if <var>starting</var> is being destroyed to match the new
12341 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012342 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 */
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012344 boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080012345 ActivityRecord starting, boolean persistent, boolean initLocale) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -070012346 // do nothing if we are headless
12347 if (mHeadless) return true;
12348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349 int changes = 0;
12350
12351 boolean kept = true;
12352
12353 if (values != null) {
12354 Configuration newConfig = new Configuration(mConfiguration);
12355 changes = newConfig.updateFrom(values);
12356 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012357 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012358 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012359 }
12360
Doug Zongker2bec3d42009-12-04 12:52:44 -080012361 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012362
Dianne Hackborn813075a62011-11-14 17:45:19 -080012363 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012364 saveLocaleLocked(values.locale,
12365 !values.locale.equals(mConfiguration.locale),
12366 values.userSetLocale);
12367 }
12368
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012369 mConfigurationSeq++;
12370 if (mConfigurationSeq <= 0) {
12371 mConfigurationSeq = 1;
12372 }
12373 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 mConfiguration = newConfig;
Craig Mautnerae446592012-12-06 19:05:05 -080012375 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012376
12377 final Configuration configCopy = new Configuration(mConfiguration);
Joe Onorato54a4a412011-11-02 20:50:08 -070012378
12379 // TODO: If our config changes, should we auto dismiss any currently
12380 // showing dialogs?
12381 mShowDialogs = shouldShowDialogs(newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012382
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012383 AttributeCache ac = AttributeCache.instance();
12384 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080012385 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012387
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012388 // Make sure all resources in our process are updated
12389 // right now, so that anyone who is going to retrieve
12390 // resource values after we return will be sure to get
12391 // the new ones. This is especially important during
12392 // boot, where the first config change needs to guarantee
12393 // all resources have that config before following boot
12394 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080012395 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012396
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012397 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012398 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012399 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012400 mHandler.sendMessage(msg);
12401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012402
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012403 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12404 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012405 try {
12406 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012407 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012408 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012409 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012410 }
12411 } catch (Exception e) {
12412 }
12413 }
12414 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012415 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070012416 | Intent.FLAG_RECEIVER_REPLACE_PENDING
12417 | Intent.FLAG_RECEIVER_FOREGROUND);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012418 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070012419 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012420 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070012421 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
12422 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12423 broadcastIntentLocked(null, null, intent,
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012424 null, null, 0, null, null,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070012425 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012427 }
12428 }
12429
12430 if (changes != 0 && starting == null) {
12431 // If the configuration changed, and the caller is not already
12432 // in the process of starting an activity, then find the top
12433 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012434 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012435 }
12436
12437 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012438 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012439 // And we need to make sure at this point that all other activities
12440 // are made visible with the correct configuration.
12441 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012442 }
12443
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012444 if (values != null && mWindowManager != null) {
12445 mWindowManager.setNewConfiguration(mConfiguration);
12446 }
12447
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012448 return kept;
12449 }
Joe Onorato54a4a412011-11-02 20:50:08 -070012450
12451 /**
12452 * Decide based on the configuration whether we should shouw the ANR,
12453 * crash, etc dialogs. The idea is that if there is no affordnace to
12454 * press the on-screen buttons, we shouldn't show the dialog.
12455 *
12456 * A thought: SystemUI might also want to get told about this, the Power
12457 * dialog / global actions also might want different behaviors.
12458 */
12459 private static final boolean shouldShowDialogs(Configuration config) {
12460 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12461 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12462 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012463
12464 /**
12465 * Save the locale. You must be inside a synchronized (this) block.
12466 */
12467 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12468 if(isDiff) {
12469 SystemProperties.set("user.language", l.getLanguage());
12470 SystemProperties.set("user.region", l.getCountry());
12471 }
12472
12473 if(isPersist) {
12474 SystemProperties.set("persist.sys.language", l.getLanguage());
12475 SystemProperties.set("persist.sys.country", l.getCountry());
12476 SystemProperties.set("persist.sys.localevar", l.getVariant());
12477 }
12478 }
12479
Adam Powelldd8fab22012-03-22 17:47:27 -070012480 @Override
12481 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12482 ActivityRecord srec = ActivityRecord.forToken(token);
Adam Powellb71a5bc2012-04-24 14:20:57 -070012483 return srec != null && srec.task.affinity != null &&
12484 srec.task.affinity.equals(destAffinity);
Adam Powelldd8fab22012-03-22 17:47:27 -070012485 }
12486
12487 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12488 Intent resultData) {
12489 ComponentName dest = destIntent.getComponent();
12490
12491 synchronized (this) {
12492 ActivityRecord srec = ActivityRecord.forToken(token);
Adam Powellb71a5bc2012-04-24 14:20:57 -070012493 if (srec == null) {
12494 return false;
12495 }
Adam Powelldd8fab22012-03-22 17:47:27 -070012496 ArrayList<ActivityRecord> history = srec.stack.mHistory;
12497 final int start = history.indexOf(srec);
12498 if (start < 0) {
12499 // Current activity is not in history stack; do nothing.
12500 return false;
12501 }
12502 int finishTo = start - 1;
12503 ActivityRecord parent = null;
12504 boolean foundParentInTask = false;
12505 if (dest != null) {
12506 TaskRecord tr = srec.task;
12507 for (int i = start - 1; i >= 0; i--) {
12508 ActivityRecord r = history.get(i);
12509 if (tr != r.task) {
12510 // Couldn't find parent in the same task; stop at the one above this.
12511 // (Root of current task; in-app "home" behavior)
12512 // Always at least finish the current activity.
12513 finishTo = Math.min(start - 1, i + 1);
12514 parent = history.get(finishTo);
12515 break;
12516 } else if (r.info.packageName.equals(dest.getPackageName()) &&
12517 r.info.name.equals(dest.getClassName())) {
12518 finishTo = i;
12519 parent = r;
12520 foundParentInTask = true;
12521 break;
12522 }
12523 }
12524 }
12525
12526 if (mController != null) {
12527 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12528 if (next != null) {
12529 // ask watcher if this is allowed
12530 boolean resumeOK = true;
12531 try {
12532 resumeOK = mController.activityResuming(next.packageName);
12533 } catch (RemoteException e) {
12534 mController = null;
12535 }
12536
12537 if (!resumeOK) {
12538 return false;
12539 }
12540 }
12541 }
12542 final long origId = Binder.clearCallingIdentity();
12543 for (int i = start; i > finishTo; i--) {
12544 ActivityRecord r = history.get(i);
12545 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -070012546 "navigate-up", true);
Adam Powelldd8fab22012-03-22 17:47:27 -070012547 // Only return the supplied result for the first activity finished
12548 resultCode = Activity.RESULT_CANCELED;
12549 resultData = null;
12550 }
12551
12552 if (parent != null && foundParentInTask) {
12553 final int parentLaunchMode = parent.info.launchMode;
12554 final int destIntentFlags = destIntent.getFlags();
12555 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12556 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12557 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12558 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
Adam Powell69de7e12012-05-07 18:42:24 -070012559 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
Adam Powelldd8fab22012-03-22 17:47:27 -070012560 } else {
12561 try {
12562 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
Amith Yamasaniea7e9152012-09-24 16:11:18 -070012563 destIntent.getComponent(), 0, srec.userId);
Adam Powelldd8fab22012-03-22 17:47:27 -070012564 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12565 null, aInfo, parent.appToken, null,
12566 0, -1, parent.launchedFromUid, 0, null, true, null);
12567 foundParentInTask = res == ActivityManager.START_SUCCESS;
12568 } catch (RemoteException e) {
12569 foundParentInTask = false;
12570 }
12571 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
Dianne Hackborn2d1b3782012-09-09 17:49:39 -070012572 resultData, "navigate-up", true);
Adam Powelldd8fab22012-03-22 17:47:27 -070012573 }
12574 }
12575 Binder.restoreCallingIdentity(origId);
12576 return foundParentInTask;
12577 }
12578 }
12579
Dianne Hackborn5320eb82012-05-18 12:05:04 -070012580 public int getLaunchedFromUid(IBinder activityToken) {
12581 ActivityRecord srec = ActivityRecord.forToken(activityToken);
12582 if (srec == null) {
12583 return -1;
12584 }
12585 return srec.launchedFromUid;
12586 }
12587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012588 // =========================================================
12589 // LIFETIME MANAGEMENT
12590 // =========================================================
12591
Christopher Tatef46723b2012-01-26 14:19:24 -080012592 // Returns which broadcast queue the app is the current [or imminent] receiver
12593 // on, or 'null' if the app is not an active broadcast recipient.
12594 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12595 BroadcastRecord r = app.curReceiver;
12596 if (r != null) {
12597 return r.queue;
12598 }
12599
12600 // It's not the current receiver, but it might be starting up to become one
12601 synchronized (this) {
12602 for (BroadcastQueue queue : mBroadcastQueues) {
12603 r = queue.mPendingBroadcast;
12604 if (r != null && r.curApp == app) {
12605 // found it; report which queue it's in
12606 return queue;
12607 }
12608 }
12609 }
12610
12611 return null;
12612 }
12613
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012614 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj, int clientHiddenAdj,
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012615 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012616 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012617 // This adjustment has already been computed. If we are calling
12618 // from the top, we may have already computed our adjustment with
12619 // an earlier hidden adjustment that isn't really for us... if
12620 // so, use the new hidden adjustment.
12621 if (!recursed && app.hidden) {
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012622 if (app.hasActivities) {
12623 app.curAdj = app.curRawAdj = app.nonStoppingAdj = hiddenAdj;
12624 } else if (app.hasClientActivities) {
12625 app.curAdj = app.curRawAdj = app.nonStoppingAdj = clientHiddenAdj;
12626 } else {
12627 app.curAdj = app.curRawAdj = app.nonStoppingAdj = emptyAdj;
12628 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012629 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012630 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012631 }
12632
12633 if (app.thread == null) {
12634 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012635 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012636 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012637 }
12638
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012639 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12640 app.adjSource = null;
12641 app.adjTarget = null;
12642 app.empty = false;
12643 app.hidden = false;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012644 app.hasClientActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012645
12646 final int activitiesSize = app.activities.size();
12647
Dianne Hackborn7d608422011-08-07 16:24:18 -070012648 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012649 // The max adjustment doesn't allow this app to be anything
12650 // below foreground, so it is not worth doing work for it.
12651 app.adjType = "fixed";
12652 app.adjSeq = mAdjSeq;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012653 app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012654 app.hasActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012655 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012656 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012657 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012658 // System process can do UI, and when they do we want to have
12659 // them trim their memory after the user leaves the UI. To
12660 // facilitate this, here we need to determine whether or not it
12661 // is currently showing UI.
12662 app.systemNoUi = true;
12663 if (app == TOP_APP) {
12664 app.systemNoUi = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012665 app.hasActivities = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012666 } else if (activitiesSize > 0) {
12667 for (int j = 0; j < activitiesSize; j++) {
12668 final ActivityRecord r = app.activities.get(j);
12669 if (r.visible) {
12670 app.systemNoUi = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012671 }
12672 if (r.app == app) {
12673 app.hasActivities = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012674 }
12675 }
12676 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012677 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012678 }
12679
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012680 app.keeping = false;
12681 app.systemNoUi = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012682 app.hasActivities = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012683
The Android Open Source Project4df24232009-03-05 14:34:35 -080012684 // Determine the importance of the process, starting with most
12685 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012686 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012687 int schedGroup;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012688 boolean foregroundActivities = false;
12689 boolean interesting = false;
Christopher Tatef46723b2012-01-26 14:19:24 -080012690 BroadcastQueue queue;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012691 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012692 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012693 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012694 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012695 app.adjType = "top-activity";
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012696 foregroundActivities = true;
12697 interesting = true;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012698 app.hasActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012699 } else if (app.instrumentationClass != null) {
12700 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012701 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012702 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012703 app.adjType = "instrumentation";
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012704 interesting = true;
Christopher Tatef46723b2012-01-26 14:19:24 -080012705 } else if ((queue = isReceivingBroadcast(app)) != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012706 // An app that is currently receiving a broadcast also
Christopher Tatef46723b2012-01-26 14:19:24 -080012707 // counts as being in the foreground for OOM killer purposes.
12708 // It's placed in a sched group based on the nature of the
12709 // broadcast as reflected by which queue it's active in.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012710 adj = ProcessList.FOREGROUND_APP_ADJ;
Christopher Tatef46723b2012-01-26 14:19:24 -080012711 schedGroup = (queue == mFgBroadcastQueue)
12712 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012713 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012714 } else if (app.executingServices.size() > 0) {
12715 // An app that is currently executing a service callback also
12716 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012717 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012718 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012719 app.adjType = "exec-service";
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012720 } else {
12721 // Assume process is hidden (has activities); we will correct
12722 // later if this is not the case.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012723 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012724 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012725 app.hidden = true;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012726 app.adjType = "bg-act";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012727 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012728
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012729 boolean hasStoppingActivities = false;
12730
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012731 // Examine all activities if not already foreground.
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012732 if (!foregroundActivities && activitiesSize > 0) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012733 for (int j = 0; j < activitiesSize; j++) {
12734 final ActivityRecord r = app.activities.get(j);
12735 if (r.visible) {
12736 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012737 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12738 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012739 app.adjType = "visible";
12740 }
12741 schedGroup = Process.THREAD_GROUP_DEFAULT;
12742 app.hidden = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012743 app.hasActivities = true;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012744 foregroundActivities = true;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012745 break;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012746 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012747 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12748 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012749 app.adjType = "pausing";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012750 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080012751 app.hidden = false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012752 foregroundActivities = true;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012753 } else if (r.state == ActivityState.STOPPING) {
12754 // We will apply the actual adjustment later, because
12755 // we want to allow this process to immediately go through
12756 // any memory trimming that is in effect.
12757 app.hidden = false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012758 foregroundActivities = true;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012759 hasStoppingActivities = true;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012760 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012761 if (r.app == app) {
12762 app.hasActivities = true;
12763 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012764 }
12765 }
12766
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012767 if (adj == hiddenAdj && !app.hasActivities) {
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012768 if (app.hasClientActivities) {
12769 adj = clientHiddenAdj;
12770 app.adjType = "bg-client-act";
12771 } else {
12772 // Whoops, this process is completely empty as far as we know
12773 // at this point.
12774 adj = emptyAdj;
12775 app.empty = true;
12776 app.adjType = "bg-empty";
12777 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012778 }
12779
Dianne Hackborn7d608422011-08-07 16:24:18 -070012780 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012781 if (app.foregroundServices) {
12782 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012783 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012784 app.hidden = false;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012785 app.adjType = "fg-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012786 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012787 } else if (app.forcingToForeground != null) {
12788 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012789 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012790 app.hidden = false;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012791 app.adjType = "force-fg";
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012792 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012793 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012794 }
12795 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012796
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012797 if (app.foregroundServices) {
12798 interesting = true;
12799 }
12800
Dianne Hackborn7d608422011-08-07 16:24:18 -070012801 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012802 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012803 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012804 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012805 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012806 app.adjType = "heavy";
12807 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012808
Dianne Hackborn7d608422011-08-07 16:24:18 -070012809 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012810 // This process is hosting what we currently consider to be the
12811 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012812 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012813 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012814 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012815 app.adjType = "home";
12816 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012817
Dianne Hackbornf35fe232011-11-01 19:25:20 -070012818 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12819 && app.activities.size() > 0) {
12820 // This was the previous process that showed UI to the user.
12821 // We want to try to keep it around more aggressively, to give
12822 // a good experience around switching between two apps.
12823 adj = ProcessList.PREVIOUS_APP_ADJ;
12824 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12825 app.hidden = false;
12826 app.adjType = "previous";
12827 }
12828
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012829 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12830 + " reason=" + app.adjType);
12831
The Android Open Source Project4df24232009-03-05 14:34:35 -080012832 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012833 // there are applications dependent on our services or providers, but
12834 // this gives us a baseline and makes sure we don't get into an
12835 // infinite recursion.
12836 app.adjSeq = mAdjSeq;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012837 app.curRawAdj = app.nonStoppingAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012838
Christopher Tate6fa95972009-06-05 18:43:55 -070012839 if (mBackupTarget != null && app == mBackupTarget.app) {
12840 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012841 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012842 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012843 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012844 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012845 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012846 }
12847 }
12848
Dianne Hackborn7d608422011-08-07 16:24:18 -070012849 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012850 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012851 final long now = SystemClock.uptimeMillis();
12852 // This process is more important if the top activity is
12853 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012854 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012855 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012856 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012857 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012858 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012859 // If this process has shown some UI, let it immediately
12860 // go to the LRU list because it may be pretty heavy with
12861 // UI stuff. We'll tag it with a label just to help
12862 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012863 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012864 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012865 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012866 } else {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070012867 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012868 // This service has seen some activity within
12869 // recent memory, so we will keep its process ahead
12870 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012871 if (adj > ProcessList.SERVICE_ADJ) {
12872 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012873 app.adjType = "started-services";
12874 app.hidden = false;
12875 }
12876 }
12877 // If we have let the service slide into the background
12878 // state, still have some text describing what it is doing
12879 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012880 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012881 app.adjType = "started-bg-services";
12882 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012883 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012884 // Don't kill this process because it is doing work; it
12885 // has said it is doing work.
12886 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012887 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012888 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012889 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012890 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012891 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012892 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012893 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012894 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012895 // XXX should compute this based on the max of
12896 // all connected clients.
12897 ConnectionRecord cr = clist.get(i);
12898 if (cr.binding.client == app) {
12899 // Binding to ourself is not interesting.
12900 continue;
12901 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012902 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012903 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012904 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012905 int myHiddenAdj = hiddenAdj;
12906 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012907 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012908 myHiddenAdj = client.hiddenAdj;
12909 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012910 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012911 }
12912 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012913 int myClientHiddenAdj = clientHiddenAdj;
12914 if (myClientHiddenAdj > client.clientHiddenAdj) {
12915 if (client.clientHiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
12916 myClientHiddenAdj = client.clientHiddenAdj;
12917 } else {
12918 myClientHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
12919 }
12920 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012921 int myEmptyAdj = emptyAdj;
12922 if (myEmptyAdj > client.emptyAdj) {
12923 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12924 myEmptyAdj = client.emptyAdj;
12925 } else {
12926 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12927 }
12928 }
12929 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012930 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012931 String adjType = null;
12932 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12933 // Not doing bind OOM management, so treat
12934 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012935 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012936 // If this process has shown some UI, let it immediately
12937 // go to the LRU list because it may be pretty heavy with
12938 // UI stuff. We'll tag it with a label just to help
12939 // debug and understand what is going on.
12940 if (adj > clientAdj) {
12941 adjType = "bound-bg-ui-services";
12942 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012943 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012944 clientAdj = adj;
12945 } else {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070012946 if (now >= (s.lastActivity
12947 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012948 // This service has not seen activity within
12949 // recent memory, so allow it to drop to the
12950 // LRU list if there is no other reason to keep
12951 // it around. We'll also tag it with a label just
12952 // to help debug and undertand what is going on.
12953 if (adj > clientAdj) {
12954 adjType = "bound-bg-services";
12955 }
12956 clientAdj = adj;
12957 }
12958 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -070012959 } else if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
12960 if ((cr.flags&Context.BIND_NOT_VISIBLE) == 0) {
12961 // If this connection is keeping the service
12962 // created, then we want to try to better follow
12963 // its memory management semantics for activities.
12964 // That is, if it is sitting in the background
12965 // LRU list as a hidden process (with activities),
12966 // we don't want the service it is connected to
12967 // to go into the empty LRU and quickly get killed,
12968 // because I'll we'll do is just end up restarting
12969 // the service.
12970 app.hasClientActivities |= client.hasActivities;
12971 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012972 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012973 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012974 // If this process has recently shown UI, and
12975 // the process that is binding to it is less
12976 // important than being visible, then we don't
12977 // care about the binding as much as we care
12978 // about letting this process get into the LRU
12979 // list to be killed and restarted if needed for
12980 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012981 if (app.hasShownUi && app != mHomeProcess
12982 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012983 adjType = "bound-bg-ui-services";
12984 } else {
12985 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12986 |Context.BIND_IMPORTANT)) != 0) {
12987 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070012988 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12989 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12990 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12991 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12992 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012993 adj = clientAdj;
12994 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070012995 app.pendingUiClean = true;
12996 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12997 adj = ProcessList.VISIBLE_APP_ADJ;
12998 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012999 }
13000 if (!client.hidden) {
13001 app.hidden = false;
13002 }
13003 if (client.keeping) {
13004 app.keeping = true;
13005 }
13006 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013007 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013008 }
13009 if (adjType != null) {
13010 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013011 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13012 .REASON_SERVICE_IN_USE;
13013 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013014 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070013015 app.adjTarget = s.name;
13016 }
13017 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13018 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13019 schedGroup = Process.THREAD_GROUP_DEFAULT;
13020 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013021 }
13022 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013023 final ActivityRecord a = cr.activity;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013024 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013025 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013026 (a.visible || a.state == ActivityState.RESUMED
13027 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013028 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013029 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
13030 schedGroup = Process.THREAD_GROUP_DEFAULT;
13031 }
13032 app.hidden = false;
13033 app.adjType = "service";
13034 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13035 .REASON_SERVICE_IN_USE;
13036 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070013037 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013038 app.adjTarget = s.name;
13039 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013040 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013041 }
13042 }
13043 }
13044 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013045
Dianne Hackborn287952c2010-09-22 22:34:31 -070013046 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013047 // would like to avoid killing it unless it would prevent the current
13048 // application from running. By default we put the process in
13049 // with the rest of the background processes; as we scan through
13050 // its services we may bump it up from there.
13051 if (adj > hiddenAdj) {
13052 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013053 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070013054 app.adjType = "bg-services";
13055 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013056 }
13057
Dianne Hackborn7d608422011-08-07 16:24:18 -070013058 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013059 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013060 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013061 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013062 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070013063 ContentProviderRecord cpr = jt.next();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070013064 for (int i = cpr.connections.size()-1;
13065 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
13066 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
13067 i--) {
13068 ContentProviderConnection conn = cpr.connections.get(i);
13069 ProcessRecord client = conn.client;
13070 if (client == app) {
13071 // Being our own client is not interesting.
13072 continue;
13073 }
13074 int myHiddenAdj = hiddenAdj;
13075 if (myHiddenAdj > client.hiddenAdj) {
13076 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
13077 myHiddenAdj = client.hiddenAdj;
13078 } else {
13079 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project10592532009-03-18 17:39:46 -070013080 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070013081 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013082 int myClientHiddenAdj = clientHiddenAdj;
13083 if (myClientHiddenAdj > client.clientHiddenAdj) {
13084 if (client.clientHiddenAdj >= ProcessList.FOREGROUND_APP_ADJ) {
13085 myClientHiddenAdj = client.clientHiddenAdj;
13086 } else {
13087 myClientHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
13088 }
13089 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013090 int myEmptyAdj = emptyAdj;
13091 if (myEmptyAdj > client.emptyAdj) {
13092 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
13093 myEmptyAdj = client.emptyAdj;
13094 } else {
13095 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
13096 }
13097 }
13098 int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013099 myClientHiddenAdj, myEmptyAdj, TOP_APP, true, doingAll);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070013100 if (adj > clientAdj) {
13101 if (app.hasShownUi && app != mHomeProcess
13102 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13103 app.adjType = "bg-ui-provider";
13104 } else {
13105 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
13106 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
13107 app.adjType = "provider";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013108 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070013109 if (!client.hidden) {
13110 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013111 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070013112 if (client.keeping) {
13113 app.keeping = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013114 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070013115 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
13116 .REASON_PROVIDER_IN_USE;
13117 app.adjSource = client;
13118 app.adjSourceOom = clientAdj;
13119 app.adjTarget = cpr.name;
13120 }
13121 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
13122 schedGroup = Process.THREAD_GROUP_DEFAULT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013123 }
13124 }
13125 // If the provider has external (non-framework) process
13126 // dependencies, ensure that its adjustment is at least
13127 // FOREGROUND_APP_ADJ.
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080013128 if (cpr.hasExternalProcessHandles()) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070013129 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
13130 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013131 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013132 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013133 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070013134 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070013135 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013136 }
13137 }
13138 }
13139 }
13140
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013141 if (adj == ProcessList.SERVICE_ADJ) {
13142 if (doingAll) {
13143 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
13144 mNewNumServiceProcs++;
13145 }
13146 if (app.serviceb) {
13147 adj = ProcessList.SERVICE_B_ADJ;
13148 }
13149 } else {
13150 app.serviceb = false;
13151 }
13152
13153 app.nonStoppingAdj = adj;
13154
13155 if (hasStoppingActivities) {
13156 // Only upgrade adjustment.
13157 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
13158 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13159 app.adjType = "stopping";
13160 }
13161 }
13162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013163 app.curRawAdj = adj;
13164
Joe Onorato8a9b2202010-02-26 18:56:32 -080013165 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013166 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
13167 if (adj > app.maxAdj) {
13168 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013169 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080013170 schedGroup = Process.THREAD_GROUP_DEFAULT;
13171 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013172 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070013173 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013174 app.keeping = true;
13175 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013176
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013177 if (app.hasAboveClient) {
13178 // If this process has bound to any services with BIND_ABOVE_CLIENT,
13179 // then we need to drop its adjustment to be lower than the service's
13180 // in order to honor the request. We want to drop it by one adjustment
13181 // level... but there is special meaning applied to various levels so
13182 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070013183 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013184 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070013185 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
13186 adj = ProcessList.VISIBLE_APP_ADJ;
13187 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
13188 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
13189 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13190 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013191 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013192 adj++;
13193 }
13194 }
13195
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013196 int importance = app.memImportance;
13197 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
13198 app.curAdj = adj;
13199 app.curSchedGroup = schedGroup;
13200 if (!interesting) {
13201 // For this reporting, if there is not something explicitly
13202 // interesting in this process then we will push it to the
13203 // background importance.
13204 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13205 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13206 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13207 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
13208 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13209 } else if (adj >= ProcessList.HOME_APP_ADJ) {
13210 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
13211 } else if (adj >= ProcessList.SERVICE_ADJ) {
13212 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
13213 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
13214 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
13215 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
13216 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
13217 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
13218 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
13219 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
13220 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
13221 } else {
13222 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
13223 }
13224 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013225
Dianne Hackborna93c2c12012-05-31 15:29:36 -070013226 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
13227 if (foregroundActivities != app.foregroundActivities) {
13228 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
13229 }
13230 if (changes != 0) {
13231 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
13232 app.memImportance = importance;
13233 app.foregroundActivities = foregroundActivities;
13234 int i = mPendingProcessChanges.size()-1;
13235 ProcessChangeItem item = null;
13236 while (i >= 0) {
13237 item = mPendingProcessChanges.get(i);
13238 if (item.pid == app.pid) {
13239 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
13240 break;
13241 }
13242 i--;
13243 }
13244 if (i < 0) {
13245 // No existing item in pending changes; need a new one.
13246 final int NA = mAvailProcessChanges.size();
13247 if (NA > 0) {
13248 item = mAvailProcessChanges.remove(NA-1);
13249 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
13250 } else {
13251 item = new ProcessChangeItem();
13252 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
13253 }
13254 item.changes = 0;
13255 item.pid = app.pid;
13256 item.uid = app.info.uid;
13257 if (mPendingProcessChanges.size() == 0) {
13258 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
13259 "*** Enqueueing dispatch processes changed!");
13260 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
13261 }
13262 mPendingProcessChanges.add(item);
13263 }
13264 item.changes |= changes;
13265 item.importance = importance;
13266 item.foregroundActivities = foregroundActivities;
13267 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
13268 + Integer.toHexString(System.identityHashCode(item))
13269 + " " + app.toShortString() + ": changes=" + item.changes
13270 + " importance=" + item.importance
13271 + " foreground=" + item.foregroundActivities
13272 + " type=" + app.adjType + " source=" + app.adjSource
13273 + " target=" + app.adjTarget);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070013274 }
13275
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013276 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013277 }
13278
13279 /**
13280 * Ask a given process to GC right now.
13281 */
13282 final void performAppGcLocked(ProcessRecord app) {
13283 try {
13284 app.lastRequestedGc = SystemClock.uptimeMillis();
13285 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013286 if (app.reportLowMemory) {
13287 app.reportLowMemory = false;
13288 app.thread.scheduleLowMemory();
13289 } else {
13290 app.thread.processInBackground();
13291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013292 }
13293 } catch (Exception e) {
13294 // whatever.
13295 }
13296 }
13297
13298 /**
13299 * Returns true if things are idle enough to perform GCs.
13300 */
Josh Bartel7f208742010-02-25 11:01:44 -060013301 private final boolean canGcNowLocked() {
Christopher Tatef46723b2012-01-26 14:19:24 -080013302 boolean processingBroadcasts = false;
13303 for (BroadcastQueue q : mBroadcastQueues) {
13304 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
13305 processingBroadcasts = true;
13306 }
13307 }
13308 return !processingBroadcasts
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013309 && (mSleeping || (mMainStack.mResumedActivity != null &&
13310 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013311 }
13312
13313 /**
13314 * Perform GCs on all processes that are waiting for it, but only
13315 * if things are idle.
13316 */
13317 final void performAppGcsLocked() {
13318 final int N = mProcessesToGc.size();
13319 if (N <= 0) {
13320 return;
13321 }
Josh Bartel7f208742010-02-25 11:01:44 -060013322 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013323 while (mProcessesToGc.size() > 0) {
13324 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013325 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013326 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
13327 <= SystemClock.uptimeMillis()) {
13328 // To avoid spamming the system, we will GC processes one
13329 // at a time, waiting a few seconds between each.
13330 performAppGcLocked(proc);
13331 scheduleAppGcsLocked();
13332 return;
13333 } else {
13334 // It hasn't been long enough since we last GCed this
13335 // process... put it in the list to wait for its time.
13336 addProcessToGcListLocked(proc);
13337 break;
13338 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013339 }
13340 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013341
13342 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013343 }
13344 }
13345
13346 /**
13347 * If all looks good, perform GCs on all processes waiting for them.
13348 */
13349 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060013350 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013351 performAppGcsLocked();
13352 return;
13353 }
13354 // Still not idle, wait some more.
13355 scheduleAppGcsLocked();
13356 }
13357
13358 /**
13359 * Schedule the execution of all pending app GCs.
13360 */
13361 final void scheduleAppGcsLocked() {
13362 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013363
13364 if (mProcessesToGc.size() > 0) {
13365 // Schedule a GC for the time to the next process.
13366 ProcessRecord proc = mProcessesToGc.get(0);
13367 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
13368
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013369 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013370 long now = SystemClock.uptimeMillis();
13371 if (when < (now+GC_TIMEOUT)) {
13372 when = now + GC_TIMEOUT;
13373 }
13374 mHandler.sendMessageAtTime(msg, when);
13375 }
13376 }
13377
13378 /**
13379 * Add a process to the array of processes waiting to be GCed. Keeps the
13380 * list in sorted order by the last GC time. The process can't already be
13381 * on the list.
13382 */
13383 final void addProcessToGcListLocked(ProcessRecord proc) {
13384 boolean added = false;
13385 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13386 if (mProcessesToGc.get(i).lastRequestedGc <
13387 proc.lastRequestedGc) {
13388 added = true;
13389 mProcessesToGc.add(i+1, proc);
13390 break;
13391 }
13392 }
13393 if (!added) {
13394 mProcessesToGc.add(0, proc);
13395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013396 }
13397
13398 /**
13399 * Set up to ask a process to GC itself. This will either do it
13400 * immediately, or put it on the list of processes to gc the next
13401 * time things are idle.
13402 */
13403 final void scheduleAppGcLocked(ProcessRecord app) {
13404 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013405 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013406 return;
13407 }
13408 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013409 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013410 scheduleAppGcsLocked();
13411 }
13412 }
13413
Dianne Hackborn287952c2010-09-22 22:34:31 -070013414 final void checkExcessivePowerUsageLocked(boolean doKills) {
13415 updateCpuStatsNow();
13416
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013417 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013418 boolean doWakeKills = doKills;
13419 boolean doCpuKills = doKills;
13420 if (mLastPowerCheckRealtime == 0) {
13421 doWakeKills = false;
13422 }
13423 if (mLastPowerCheckUptime == 0) {
13424 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013425 }
13426 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013427 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013428 }
13429 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013430 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13431 final long curUptime = SystemClock.uptimeMillis();
13432 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13433 mLastPowerCheckRealtime = curRealtime;
13434 mLastPowerCheckUptime = curUptime;
13435 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13436 doWakeKills = false;
13437 }
13438 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13439 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013440 }
13441 int i = mLruProcesses.size();
13442 while (i > 0) {
13443 i--;
13444 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013445 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013446 long wtime;
13447 synchronized (stats) {
13448 wtime = stats.getProcessWakeTime(app.info.uid,
13449 app.pid, curRealtime);
13450 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013451 long wtimeUsed = wtime - app.lastWakeTime;
13452 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13453 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013454 StringBuilder sb = new StringBuilder(128);
13455 sb.append("Wake for ");
13456 app.toShortString(sb);
13457 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013458 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013459 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013460 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013461 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013462 sb.append((wtimeUsed*100)/realtimeSince);
13463 sb.append("%)");
13464 Slog.i(TAG, sb.toString());
13465 sb.setLength(0);
13466 sb.append("CPU for ");
13467 app.toShortString(sb);
13468 sb.append(": over ");
13469 TimeUtils.formatDuration(uptimeSince, sb);
13470 sb.append(" used ");
13471 TimeUtils.formatDuration(cputimeUsed, sb);
13472 sb.append(" (");
13473 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013474 sb.append("%)");
13475 Slog.i(TAG, sb.toString());
13476 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013477 // If a process has held a wake lock for more
13478 // than 50% of the time during this period,
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013479 // that sounds bad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013480 if (doWakeKills && realtimeSince > 0
13481 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13482 synchronized (stats) {
13483 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13484 realtimeSince, wtimeUsed);
13485 }
13486 Slog.w(TAG, "Excessive wake lock in " + app.processName
13487 + " (pid " + app.pid + "): held " + wtimeUsed
13488 + " during " + realtimeSince);
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013489 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013490 app.processName, app.setAdj, "excessive wake lock");
13491 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013492 } else if (doCpuKills && uptimeSince > 0
13493 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13494 synchronized (stats) {
13495 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13496 uptimeSince, cputimeUsed);
13497 }
13498 Slog.w(TAG, "Excessive CPU in " + app.processName
13499 + " (pid " + app.pid + "): used " + cputimeUsed
13500 + " during " + uptimeSince);
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013501 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Dianne Hackborn287952c2010-09-22 22:34:31 -070013502 app.processName, app.setAdj, "excessive cpu");
13503 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013504 } else {
13505 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013506 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013507 }
13508 }
13509 }
13510 }
13511
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013512 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013513 int clientHiddenAdj, int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013514 app.hiddenAdj = hiddenAdj;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013515 app.clientHiddenAdj = clientHiddenAdj;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013516 app.emptyAdj = emptyAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517
13518 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013519 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013520 }
13521
Dianne Hackborn287952c2010-09-22 22:34:31 -070013522 final boolean wasKeeping = app.keeping;
13523
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013524 boolean success = true;
13525
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013526 computeOomAdjLocked(app, hiddenAdj, clientHiddenAdj, emptyAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013527
Jeff Brown10e89712011-07-08 18:52:57 -070013528 if (app.curRawAdj != app.setRawAdj) {
Jeff Brown10e89712011-07-08 18:52:57 -070013529 if (wasKeeping && !app.keeping) {
13530 // This app is no longer something we want to keep. Note
13531 // its current wake lock time to later know to kill it if
13532 // it is not behaving well.
13533 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13534 synchronized (stats) {
13535 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13536 app.pid, SystemClock.elapsedRealtime());
13537 }
13538 app.lastCpuTime = app.curCpuTime;
13539 }
13540
13541 app.setRawAdj = app.curRawAdj;
13542 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013543
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013544 if (app.curAdj != app.setAdj) {
13545 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080013546 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013547 TAG, "Set " + app.pid + " " + app.processName +
13548 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013549 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013550 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013551 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013552 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013553 }
13554 }
13555 if (app.setSchedGroup != app.curSchedGroup) {
13556 app.setSchedGroup = app.curSchedGroup;
13557 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13558 "Setting process group of " + app.processName
13559 + " to " + app.curSchedGroup);
13560 if (app.waitingToKill != null &&
13561 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13562 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013563 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Jeff Brown10e89712011-07-08 18:52:57 -070013564 app.processName, app.setAdj, app.waitingToKill);
Dianne Hackborn45a25bc2012-06-28 13:49:17 -070013565 app.killedBackground = true;
Jeff Brown10e89712011-07-08 18:52:57 -070013566 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013567 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013568 } else {
13569 if (true) {
13570 long oldId = Binder.clearCallingIdentity();
13571 try {
13572 Process.setProcessGroup(app.pid, app.curSchedGroup);
13573 } catch (Exception e) {
13574 Slog.w(TAG, "Failed setting process group of " + app.pid
13575 + " to " + app.curSchedGroup);
13576 e.printStackTrace();
13577 } finally {
13578 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013579 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013580 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013581 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013582 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013583 app.thread.setSchedulingGroup(app.curSchedGroup);
13584 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013585 }
13586 }
13587 }
13588 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013589 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013590 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013591 }
13592
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013593 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013594 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013595 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -080013596 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013597 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013598 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013599 }
13600 }
13601 return resumedActivity;
13602 }
13603
Dianne Hackborn599db5c2012-08-03 19:28:48 -070013604 final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013605 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013606 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13607 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013608 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13609 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013610
13611 mAdjSeq++;
13612
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013613 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.clientHiddenAdj,
13614 app.emptyAdj, TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013615 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13616 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013617 if (nowHidden != wasHidden) {
13618 // Changed to/from hidden state, so apps after it in the LRU
13619 // list may also be changed.
13620 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013621 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013622 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013623 }
13624
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013625 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013626 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013627 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013628 final long oldTime = SystemClock.uptimeMillis() - ProcessList.MAX_EMPTY_TIME;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013629
13630 if (false) {
13631 RuntimeException e = new RuntimeException();
13632 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013633 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013634 }
13635
13636 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013637 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013638
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013639 final int emptyProcessLimit;
13640 final int hiddenProcessLimit;
13641 if (mProcessLimit <= 0) {
13642 emptyProcessLimit = hiddenProcessLimit = 0;
13643 } else if (mProcessLimit == 1) {
13644 emptyProcessLimit = 1;
13645 hiddenProcessLimit = 0;
13646 } else {
13647 emptyProcessLimit = (mProcessLimit*2)/3;
13648 hiddenProcessLimit = mProcessLimit - emptyProcessLimit;
13649 }
13650
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013651 // Let's determine how many processes we have running vs.
13652 // how many slots we have for background processes; we may want
13653 // to put multiple processes in a slot of there are enough of
13654 // them.
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013655 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13656 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013657 int numEmptyProcs = mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs;
13658 if (numEmptyProcs > hiddenProcessLimit) {
13659 // If there are more empty processes than our limit on hidden
13660 // processes, then use the hidden process limit for the factor.
13661 // This ensures that the really old empty processes get pushed
13662 // down to the bottom, so if we are running low on memory we will
13663 // have a better chance at keeping around more hidden processes
13664 // instead of a gazillion empty processes.
13665 numEmptyProcs = hiddenProcessLimit;
13666 }
13667 int emptyFactor = numEmptyProcs/numSlots;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013668 if (emptyFactor < 1) emptyFactor = 1;
13669 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13670 if (hiddenFactor < 1) hiddenFactor = 1;
13671 int stepHidden = 0;
13672 int stepEmpty = 0;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013673 int numHidden = 0;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013674 int numEmpty = 0;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013675 int numTrimming = 0;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013676
13677 mNumNonHiddenProcs = 0;
13678 mNumHiddenProcs = 0;
13679
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013680 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013681 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013682 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013683 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013684 int nextHiddenAdj = curHiddenAdj+1;
13685 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13686 int nextEmptyAdj = curEmptyAdj+2;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013687 int curClientHiddenAdj = curEmptyAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013688 while (i > 0) {
13689 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013690 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013691 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013692 updateOomAdjLocked(app, curHiddenAdj, curClientHiddenAdj, curEmptyAdj, TOP_APP, true);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013693 if (!app.killedBackground) {
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013694 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13695 // This process was assigned as a hidden process... step the
13696 // hidden level.
13697 mNumHiddenProcs++;
13698 if (curHiddenAdj != nextHiddenAdj) {
13699 stepHidden++;
13700 if (stepHidden >= hiddenFactor) {
13701 stepHidden = 0;
13702 curHiddenAdj = nextHiddenAdj;
13703 nextHiddenAdj += 2;
13704 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13705 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13706 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013707 if (curClientHiddenAdj <= curHiddenAdj) {
13708 curClientHiddenAdj = curHiddenAdj + 1;
13709 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13710 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13711 }
13712 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013713 }
13714 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013715 numHidden++;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013716 if (numHidden > hiddenProcessLimit) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013717 Slog.i(TAG, "No longer want " + app.processName
13718 + " (pid " + app.pid + "): hidden #" + numHidden);
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013719 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013720 app.processName, app.setAdj, "too many background");
13721 app.killedBackground = true;
13722 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070013723 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013724 } else if (app.curRawAdj == curHiddenAdj && app.hasClientActivities) {
13725 // This process has a client that has activities. We will have
13726 // given it the current hidden adj; here we will just leave it
13727 // without stepping the hidden adj.
13728 curClientHiddenAdj++;
13729 if (curClientHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13730 curClientHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13731 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013732 } else {
13733 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13734 // This process was assigned as an empty process... step the
13735 // empty level.
13736 if (curEmptyAdj != nextEmptyAdj) {
13737 stepEmpty++;
13738 if (stepEmpty >= emptyFactor) {
13739 stepEmpty = 0;
13740 curEmptyAdj = nextEmptyAdj;
13741 nextEmptyAdj += 2;
13742 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13743 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13744 }
13745 }
13746 }
13747 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13748 mNumNonHiddenProcs++;
13749 }
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013750 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13751 && !app.hasClientActivities) {
13752 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
13753 && app.lastActivityTime < oldTime) {
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013754 Slog.i(TAG, "No longer want " + app.processName
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013755 + " (pid " + app.pid + "): empty for "
13756 + ((oldTime+ProcessList.MAX_EMPTY_TIME-app.lastActivityTime)
13757 / 1000) + "s");
13758 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13759 app.processName, app.setAdj, "old background process");
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013760 app.killedBackground = true;
13761 Process.killProcessQuiet(app.pid);
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013762 } else {
13763 numEmpty++;
13764 if (numEmpty > emptyProcessLimit) {
13765 Slog.i(TAG, "No longer want " + app.processName
13766 + " (pid " + app.pid + "): empty #" + numEmpty);
13767 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
13768 app.processName, app.setAdj, "too many background");
13769 app.killedBackground = true;
13770 Process.killProcessQuiet(app.pid);
13771 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013772 }
13773 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013774 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013775 if (app.isolated && app.services.size() <= 0) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013776 // If this is an isolated process, and there are no
13777 // services running in it, then the process is no longer
13778 // needed. We agressively kill these because we can by
13779 // definition not re-use the same process again, and it is
13780 // good to avoid having whatever code was running in them
13781 // left sitting around after no longer needed.
13782 Slog.i(TAG, "Isolated process " + app.processName
13783 + " (pid " + app.pid + ") no longer needed");
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013784 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013785 app.processName, app.setAdj, "isolated not needed");
13786 app.killedBackground = true;
13787 Process.killProcessQuiet(app.pid);
13788 }
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013789 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13790 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13791 && !app.killedBackground) {
13792 numTrimming++;
13793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013794 }
13795 }
13796
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013797 mNumServiceProcs = mNewNumServiceProcs;
13798
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013799 // Now determine the memory trimming level of background processes.
13800 // Unfortunately we need to start at the back of the list to do this
13801 // properly. We only do this if the number of background apps we
13802 // are managing to keep around is less than half the maximum we desire;
13803 // if we are keeping a good number around, we'll let them use whatever
13804 // memory they want.
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013805 if (numHidden <= ProcessList.TRIM_HIDDEN_APPS
13806 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013807 final int numHiddenAndEmpty = numHidden + numEmpty;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013808 final int N = mLruProcesses.size();
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013809 int factor = numTrimming/3;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080013810 int minFactor = 2;
13811 if (mHomeProcess != null) minFactor++;
13812 if (mPreviousProcess != null) minFactor++;
13813 if (factor < minFactor) factor = minFactor;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013814 int step = 0;
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013815 int fgTrimLevel;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013816 if (numHiddenAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013817 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013818 } else if (numHiddenAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013819 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13820 } else {
13821 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13822 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013823 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013824 for (i=0; i<N; i++) {
13825 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013826 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13827 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080013828 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013829 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13830 try {
13831 app.thread.scheduleTrimMemory(curLevel);
13832 } catch (RemoteException e) {
13833 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080013834 if (false) {
13835 // For now we won't do this; our memory trimming seems
13836 // to be good enough at this point that destroying
13837 // activities causes more harm than good.
13838 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13839 && app != mHomeProcess && app != mPreviousProcess) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070013840 // Need to do this on its own message because the stack may not
13841 // be in a consistent state at this point.
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080013842 // For these apps we will also finish their activities
13843 // to help them free memory.
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070013844 mMainStack.scheduleDestroyActivities(app, false, "trim");
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080013845 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013846 }
13847 }
13848 app.trimMemoryLevel = curLevel;
13849 step++;
13850 if (step >= factor) {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013851 step = 0;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013852 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013853 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13854 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013855 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013856 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13857 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013858 break;
13859 }
13860 }
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013861 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013862 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013863 && app.thread != null) {
13864 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013865 app.thread.scheduleTrimMemory(
13866 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013867 } catch (RemoteException e) {
13868 }
13869 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013870 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013871 } else {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013872 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013873 && app.pendingUiClean) {
13874 // If this application is now in the background and it
13875 // had done UI, then give it the special trim level to
13876 // have it free UI resources.
13877 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13878 if (app.trimMemoryLevel < level && app.thread != null) {
13879 try {
13880 app.thread.scheduleTrimMemory(level);
13881 } catch (RemoteException e) {
13882 }
13883 }
13884 app.pendingUiClean = false;
13885 }
13886 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013887 try {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013888 app.thread.scheduleTrimMemory(fgTrimLevel);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013889 } catch (RemoteException e) {
13890 }
13891 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013892 app.trimMemoryLevel = fgTrimLevel;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013893 }
13894 }
13895 } else {
13896 final int N = mLruProcesses.size();
13897 for (i=0; i<N; i++) {
13898 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013899 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013900 && app.pendingUiClean) {
13901 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13902 && app.thread != null) {
13903 try {
13904 app.thread.scheduleTrimMemory(
13905 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13906 } catch (RemoteException e) {
13907 }
13908 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013909 app.pendingUiClean = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013910 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013911 app.trimMemoryLevel = 0;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013912 }
13913 }
13914
13915 if (mAlwaysFinishActivities) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070013916 // Need to do this on its own message because the stack may not
13917 // be in a consistent state at this point.
13918 mMainStack.scheduleDestroyActivities(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013919 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013920 }
13921
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013922 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013923 synchronized (this) {
13924 int i;
13925
13926 // First remove any unused application processes whose package
13927 // has been removed.
13928 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13929 final ProcessRecord app = mRemovedProcesses.get(i);
13930 if (app.activities.size() == 0
13931 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013932 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013933 TAG, "Exiting empty application process "
13934 + app.processName + " ("
13935 + (app.thread != null ? app.thread.asBinder() : null)
13936 + ")\n");
13937 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackbornb12e1352012-09-26 11:39:20 -070013938 EventLog.writeEvent(EventLogTags.AM_KILL, app.userId, app.pid,
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013939 app.processName, app.setAdj, "empty");
13940 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013941 } else {
13942 try {
13943 app.thread.scheduleExit();
13944 } catch (Exception e) {
13945 // Ignore exceptions.
13946 }
13947 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013948 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013949 mRemovedProcesses.remove(i);
13950
13951 if (app.persistent) {
13952 if (app.persistent) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013953 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013954 }
13955 }
13956 }
13957 }
13958
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013959 // Now update the oom adj for all processes.
13960 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013961 }
13962 }
13963
13964 /** This method sends the specified signal to each of the persistent apps */
13965 public void signalPersistentProcesses(int sig) throws RemoteException {
13966 if (sig != Process.SIGNAL_USR1) {
13967 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13968 }
13969
13970 synchronized (this) {
13971 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13972 != PackageManager.PERMISSION_GRANTED) {
13973 throw new SecurityException("Requires permission "
13974 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13975 }
13976
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013977 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13978 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013979 if (r.thread != null && r.persistent) {
13980 Process.sendSignal(r.pid, sig);
13981 }
13982 }
13983 }
13984 }
13985
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013986 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13987 if (proc == null || proc == mProfileProc) {
13988 proc = mProfileProc;
13989 path = mProfileFile;
13990 profileType = mProfileType;
13991 clearProfilerLocked();
13992 }
13993 if (proc == null) {
13994 return;
13995 }
13996 try {
13997 proc.thread.profilerControl(false, path, null, profileType);
13998 } catch (RemoteException e) {
13999 throw new IllegalStateException("Process disappeared");
14000 }
14001 }
14002
14003 private void clearProfilerLocked() {
14004 if (mProfileFd != null) {
14005 try {
14006 mProfileFd.close();
14007 } catch (IOException e) {
14008 }
14009 }
14010 mProfileApp = null;
14011 mProfileProc = null;
14012 mProfileFile = null;
14013 mProfileType = 0;
14014 mAutoStopProfiler = false;
14015 }
14016
Dianne Hackborn1676c852012-09-10 14:52:30 -070014017 public boolean profileControl(String process, int userId, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070014018 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014019
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014020 try {
14021 synchronized (this) {
14022 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14023 // its own permission.
14024 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14025 != PackageManager.PERMISSION_GRANTED) {
14026 throw new SecurityException("Requires permission "
14027 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014028 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014029
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014030 if (start && fd == null) {
14031 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014032 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014033
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014034 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014035 if (process != null) {
Dianne Hackborn1676c852012-09-10 14:52:30 -070014036 proc = findProcessLocked(process, userId, "profileControl");
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014037 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014038
14039 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014040 throw new IllegalArgumentException("Unknown process: " + process);
14041 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014042
14043 if (start) {
14044 stopProfilerLocked(null, null, 0);
14045 setProfileApp(proc.info, proc.processName, path, fd, false);
14046 mProfileProc = proc;
14047 mProfileType = profileType;
14048 try {
14049 fd = fd.dup();
14050 } catch (IOException e) {
14051 fd = null;
14052 }
14053 proc.thread.profilerControl(start, path, fd, profileType);
14054 fd = null;
14055 mProfileFd = null;
14056 } else {
14057 stopProfilerLocked(proc, path, profileType);
14058 if (fd != null) {
14059 try {
14060 fd.close();
14061 } catch (IOException e) {
14062 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014063 }
14064 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070014065
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014066 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070014067 }
14068 } catch (RemoteException e) {
14069 throw new IllegalStateException("Process disappeared");
14070 } finally {
14071 if (fd != null) {
14072 try {
14073 fd.close();
14074 } catch (IOException e) {
14075 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080014076 }
14077 }
14078 }
Andy McFadden824c5102010-07-09 16:26:57 -070014079
Dianne Hackborn1676c852012-09-10 14:52:30 -070014080 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
Dianne Hackborn139748f2012-09-24 11:36:57 -070014081 userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackborn1676c852012-09-10 14:52:30 -070014082 userId, true, true, callName, null);
14083 ProcessRecord proc = null;
14084 try {
14085 int pid = Integer.parseInt(process);
14086 synchronized (mPidsSelfLocked) {
14087 proc = mPidsSelfLocked.get(pid);
14088 }
14089 } catch (NumberFormatException e) {
14090 }
14091
14092 if (proc == null) {
14093 HashMap<String, SparseArray<ProcessRecord>> all
14094 = mProcessNames.getMap();
14095 SparseArray<ProcessRecord> procs = all.get(process);
14096 if (procs != null && procs.size() > 0) {
14097 proc = procs.valueAt(0);
14098 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
14099 for (int i=1; i<procs.size(); i++) {
14100 ProcessRecord thisProc = procs.valueAt(i);
14101 if (thisProc.userId == userId) {
14102 proc = thisProc;
14103 break;
14104 }
14105 }
14106 }
14107 }
14108 }
14109
14110 return proc;
14111 }
14112
14113 public boolean dumpHeap(String process, int userId, boolean managed,
Andy McFadden824c5102010-07-09 16:26:57 -070014114 String path, ParcelFileDescriptor fd) throws RemoteException {
14115
14116 try {
14117 synchronized (this) {
14118 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
14119 // its own permission (same as profileControl).
14120 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
14121 != PackageManager.PERMISSION_GRANTED) {
14122 throw new SecurityException("Requires permission "
14123 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
14124 }
14125
14126 if (fd == null) {
14127 throw new IllegalArgumentException("null fd");
14128 }
14129
Dianne Hackborn1676c852012-09-10 14:52:30 -070014130 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
Andy McFadden824c5102010-07-09 16:26:57 -070014131 if (proc == null || proc.thread == null) {
14132 throw new IllegalArgumentException("Unknown process: " + process);
14133 }
14134
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080014135 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
14136 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070014137 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
14138 throw new SecurityException("Process not debuggable: " + proc);
14139 }
14140 }
14141
14142 proc.thread.dumpHeap(managed, path, fd);
14143 fd = null;
14144 return true;
14145 }
14146 } catch (RemoteException e) {
14147 throw new IllegalStateException("Process disappeared");
14148 } finally {
14149 if (fd != null) {
14150 try {
14151 fd.close();
14152 } catch (IOException e) {
14153 }
14154 }
14155 }
14156 }
14157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014158 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
14159 public void monitor() {
14160 synchronized (this) { }
14161 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014162
Dianne Hackborna573f6a2012-02-09 16:12:18 -080014163 void onCoreSettingsChange(Bundle settings) {
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080014164 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14165 ProcessRecord processRecord = mLruProcesses.get(i);
14166 try {
14167 if (processRecord.thread != null) {
14168 processRecord.thread.setCoreSettings(settings);
14169 }
14170 } catch (RemoteException re) {
14171 /* ignore */
14172 }
14173 }
14174 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014175
14176 // Multi-user methods
14177
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014178 @Override
Dianne Hackborn4d78abf2012-11-29 15:10:18 -080014179 public boolean switchUser(final int userId) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014180 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14181 != PackageManager.PERMISSION_GRANTED) {
14182 String msg = "Permission Denial: switchUser() from pid="
14183 + Binder.getCallingPid()
14184 + ", uid=" + Binder.getCallingUid()
14185 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14186 Slog.w(TAG, msg);
14187 throw new SecurityException(msg);
Amith Yamasani742a6712011-05-04 14:49:28 -070014188 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014189
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014190 final long ident = Binder.clearCallingIdentity();
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014191 try {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014192 synchronized (this) {
14193 final int oldUserId = mCurrentUserId;
14194 if (oldUserId == userId) {
14195 return true;
14196 }
14197
14198 final UserInfo userInfo = getUserManagerLocked().getUserInfo(userId);
14199 if (userInfo == null) {
14200 Slog.w(TAG, "No user info for user #" + userId);
14201 return false;
14202 }
14203
14204 mWindowManager.startFreezingScreen(R.anim.screen_user_exit,
14205 R.anim.screen_user_enter);
14206
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014207 boolean needStart = false;
14208
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014209 // If the user we are switching to is not currently started, then
14210 // we need to start it now.
14211 if (mStartedUsers.get(userId) == null) {
14212 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
Dianne Hackbornc72fc672012-09-20 13:12:03 -070014213 updateStartedUserArrayLocked();
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014214 needStart = true;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014215 }
14216
14217 mCurrentUserId = userId;
Dianne Hackbornc72fc672012-09-20 13:12:03 -070014218 mCurrentUserArray = new int[] { userId };
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014219 final Integer userIdInt = Integer.valueOf(userId);
14220 mUserLru.remove(userIdInt);
14221 mUserLru.add(userIdInt);
14222
Craig Mautnerf1b67412012-09-19 13:18:29 -070014223 mWindowManager.setCurrentUser(userId);
14224
Adam Cohenf7522022012-10-03 20:03:18 -070014225 // Once the internal notion of the active user has switched, we lock the device
14226 // with the option to show the user switcher on the keyguard.
Winson Chungf7614fc2012-11-26 14:43:24 -080014227 mWindowManager.lockNow(null);
Adam Cohenf7522022012-10-03 20:03:18 -070014228
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014229 final UserStartedState uss = mStartedUsers.get(userId);
14230
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014231 // Make sure user is in the started state. If it is currently
14232 // stopping, we need to knock that off.
14233 if (uss.mState == UserStartedState.STATE_STOPPING) {
14234 // If we are stopping, we haven't sent ACTION_SHUTDOWN,
14235 // so we can just fairly silently bring the user back from
14236 // the almost-dead.
14237 uss.mState = UserStartedState.STATE_RUNNING;
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014238 updateStartedUserArrayLocked();
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014239 needStart = true;
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014240 } else if (uss.mState == UserStartedState.STATE_SHUTDOWN) {
14241 // This means ACTION_SHUTDOWN has been sent, so we will
14242 // need to treat this as a new boot of the user.
14243 uss.mState = UserStartedState.STATE_BOOTING;
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014244 updateStartedUserArrayLocked();
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014245 needStart = true;
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014246 }
14247
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014248 mHandler.removeMessages(REPORT_USER_SWITCH_MSG);
14249 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14250 mHandler.sendMessage(mHandler.obtainMessage(REPORT_USER_SWITCH_MSG,
14251 oldUserId, userId, uss));
14252 mHandler.sendMessageDelayed(mHandler.obtainMessage(USER_SWITCH_TIMEOUT_MSG,
14253 oldUserId, userId, uss), USER_SWITCH_TIMEOUT);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014254 if (needStart) {
14255 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
14256 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14257 | Intent.FLAG_RECEIVER_FOREGROUND);
14258 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14259 broadcastIntentLocked(null, null, intent,
14260 null, null, 0, null, null, null,
14261 false, false, MY_PID, Process.SYSTEM_UID, userId);
14262 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014263
14264 if ((userInfo.flags&UserInfo.FLAG_INITIALIZED) == 0) {
14265 if (userId != 0) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014266 Intent intent = new Intent(Intent.ACTION_USER_INITIALIZE);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014267 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014268 broadcastIntentLocked(null, null, intent, null,
14269 new IIntentReceiver.Stub() {
14270 public void performReceive(Intent intent, int resultCode,
14271 String data, Bundle extras, boolean ordered,
14272 boolean sticky, int sendingUser) {
Dianne Hackborn4d78abf2012-11-29 15:10:18 -080014273 userInitialized(uss, userId);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014274 }
14275 }, 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
14276 userId);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014277 uss.initializing = true;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014278 } else {
14279 getUserManagerLocked().makeInitialized(userInfo.id);
14280 }
14281 }
14282
14283 boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
14284 if (!haveActivities) {
14285 startHomeActivityLocked(userId);
14286 }
Craig Mautnerf1b67412012-09-19 13:18:29 -070014287
Jeff Sharkey86597df2012-11-09 15:00:31 -080014288 EventLogTags.writeAmSwitchUser(userId);
Amith Yamasani920ace02012-09-20 22:15:37 -070014289 getUserManagerLocked().userForeground(userId);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014290 sendUserSwitchBroadcastsLocked(oldUserId, userId);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014291 if (needStart) {
14292 Intent intent = new Intent(Intent.ACTION_USER_STARTING);
14293 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14294 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14295 broadcastIntentLocked(null, null, intent,
14296 null, new IIntentReceiver.Stub() {
14297 @Override
14298 public void performReceive(Intent intent, int resultCode, String data,
14299 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
14300 throws RemoteException {
14301 }
14302 }, 0, null, null,
14303 android.Manifest.permission.INTERACT_ACROSS_USERS,
Dianne Hackborn40e9f292012-11-27 19:12:23 -080014304 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -070014305 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014306 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014307 } finally {
14308 Binder.restoreCallingIdentity(ident);
14309 }
Amith Yamasani13593602012-03-22 16:16:17 -070014310
Amith Yamasani4b2e9342011-03-31 12:38:53 -070014311 return true;
14312 }
Amith Yamasani742a6712011-05-04 14:49:28 -070014313
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014314 void sendUserSwitchBroadcastsLocked(int oldUserId, int newUserId) {
14315 long ident = Binder.clearCallingIdentity();
14316 try {
14317 Intent intent;
14318 if (oldUserId >= 0) {
14319 intent = new Intent(Intent.ACTION_USER_BACKGROUND);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014320 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14321 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014322 intent.putExtra(Intent.EXTRA_USER_HANDLE, oldUserId);
14323 broadcastIntentLocked(null, null, intent,
14324 null, null, 0, null, null, null,
14325 false, false, MY_PID, Process.SYSTEM_UID, oldUserId);
14326 }
14327 if (newUserId >= 0) {
14328 intent = new Intent(Intent.ACTION_USER_FOREGROUND);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014329 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14330 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014331 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14332 broadcastIntentLocked(null, null, intent,
14333 null, null, 0, null, null, null,
14334 false, false, MY_PID, Process.SYSTEM_UID, newUserId);
14335 intent = new Intent(Intent.ACTION_USER_SWITCHED);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014336 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
14337 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014338 intent.putExtra(Intent.EXTRA_USER_HANDLE, newUserId);
14339 broadcastIntentLocked(null, null, intent,
14340 null, null, 0, null, null,
14341 android.Manifest.permission.MANAGE_USERS,
14342 false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
14343 }
14344 } finally {
14345 Binder.restoreCallingIdentity(ident);
14346 }
14347 }
14348
14349 void dispatchUserSwitch(final UserStartedState uss, final int oldUserId,
14350 final int newUserId) {
14351 final int N = mUserSwitchObservers.beginBroadcast();
14352 if (N > 0) {
14353 final IRemoteCallback callback = new IRemoteCallback.Stub() {
14354 int mCount = 0;
14355 @Override
14356 public void sendResult(Bundle data) throws RemoteException {
14357 synchronized (ActivityManagerService.this) {
14358 if (mCurUserSwitchCallback == this) {
14359 mCount++;
14360 if (mCount == N) {
14361 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14362 }
14363 }
14364 }
14365 }
14366 };
14367 synchronized (this) {
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014368 uss.switching = true;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014369 mCurUserSwitchCallback = callback;
14370 }
14371 for (int i=0; i<N; i++) {
14372 try {
14373 mUserSwitchObservers.getBroadcastItem(i).onUserSwitching(
14374 newUserId, callback);
14375 } catch (RemoteException e) {
14376 }
14377 }
14378 } else {
14379 synchronized (this) {
14380 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14381 }
14382 }
14383 mUserSwitchObservers.finishBroadcast();
14384 }
14385
14386 void timeoutUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
14387 synchronized (this) {
14388 Slog.w(TAG, "User switch timeout: from " + oldUserId + " to " + newUserId);
14389 sendContinueUserSwitchLocked(uss, oldUserId, newUserId);
14390 }
14391 }
14392
14393 void sendContinueUserSwitchLocked(UserStartedState uss, int oldUserId, int newUserId) {
14394 mCurUserSwitchCallback = null;
14395 mHandler.removeMessages(USER_SWITCH_TIMEOUT_MSG);
14396 mHandler.sendMessage(mHandler.obtainMessage(CONTINUE_USER_SWITCH_MSG,
14397 oldUserId, newUserId, uss));
14398 }
14399
Dianne Hackborn4d78abf2012-11-29 15:10:18 -080014400 void userInitialized(UserStartedState uss, int newUserId) {
14401 completeSwitchAndInitalize(uss, newUserId, true, false);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014402 }
14403
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014404 void continueUserSwitch(UserStartedState uss, int oldUserId, int newUserId) {
Dianne Hackborn4d78abf2012-11-29 15:10:18 -080014405 completeSwitchAndInitalize(uss, newUserId, false, true);
Dianne Hackbornd4ac8d72012-09-27 23:20:10 -070014406 }
14407
Dianne Hackborn4d78abf2012-11-29 15:10:18 -080014408 void completeSwitchAndInitalize(UserStartedState uss, int newUserId,
14409 boolean clearInitializing, boolean clearSwitching) {
14410 boolean unfrozen = false;
14411 synchronized (this) {
14412 if (clearInitializing) {
14413 uss.initializing = false;
14414 getUserManagerLocked().makeInitialized(uss.mHandle.getIdentifier());
14415 }
14416 if (clearSwitching) {
14417 uss.switching = false;
14418 }
14419 if (!uss.switching && !uss.initializing) {
14420 mWindowManager.stopFreezingScreen();
14421 unfrozen = true;
14422 }
14423 }
14424 if (unfrozen) {
14425 final int N = mUserSwitchObservers.beginBroadcast();
14426 for (int i=0; i<N; i++) {
14427 try {
14428 mUserSwitchObservers.getBroadcastItem(i).onUserSwitchComplete(newUserId);
14429 } catch (RemoteException e) {
14430 }
14431 }
14432 mUserSwitchObservers.finishBroadcast();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014433 }
14434 }
14435
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014436 void finishUserSwitch(UserStartedState uss) {
14437 synchronized (this) {
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014438 if (uss.mState == UserStartedState.STATE_BOOTING
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014439 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
14440 uss.mState = UserStartedState.STATE_RUNNING;
Dianne Hackborn41203752012-08-31 14:05:51 -070014441 final int userId = uss.mHandle.getIdentifier();
14442 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
14443 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14444 broadcastIntentLocked(null, null, intent,
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014445 null, null, 0, null, null,
14446 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Dianne Hackborn41203752012-08-31 14:05:51 -070014447 false, false, MY_PID, Process.SYSTEM_UID, userId);
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014448 }
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014449 int num = mUserLru.size();
14450 int i = 0;
14451 while (num > MAX_RUNNING_USERS && i < mUserLru.size()) {
14452 Integer oldUserId = mUserLru.get(i);
14453 UserStartedState oldUss = mStartedUsers.get(oldUserId);
14454 if (oldUss == null) {
14455 // Shouldn't happen, but be sane if it does.
14456 mUserLru.remove(i);
14457 num--;
14458 continue;
14459 }
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014460 if (oldUss.mState == UserStartedState.STATE_STOPPING
14461 || oldUss.mState == UserStartedState.STATE_SHUTDOWN) {
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014462 // This user is already stopping, doesn't count.
14463 num--;
14464 i++;
14465 continue;
14466 }
14467 if (oldUserId == UserHandle.USER_OWNER || oldUserId == mCurrentUserId) {
14468 // Owner and current can't be stopped, but count as running.
14469 i++;
14470 continue;
14471 }
14472 // This is a user to be stopped.
14473 stopUserLocked(oldUserId, null);
14474 num--;
14475 i++;
14476 }
Amith Yamasani52f1d752012-03-28 18:19:29 -070014477 }
Amith Yamasani52f1d752012-03-28 18:19:29 -070014478 }
14479
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014480 @Override
14481 public int stopUser(final int userId, final IStopUserCallback callback) {
14482 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14483 != PackageManager.PERMISSION_GRANTED) {
14484 String msg = "Permission Denial: switchUser() from pid="
14485 + Binder.getCallingPid()
14486 + ", uid=" + Binder.getCallingUid()
14487 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14488 Slog.w(TAG, msg);
14489 throw new SecurityException(msg);
14490 }
14491 if (userId <= 0) {
14492 throw new IllegalArgumentException("Can't stop primary user " + userId);
14493 }
Amith Yamasani13593602012-03-22 16:16:17 -070014494 synchronized (this) {
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014495 return stopUserLocked(userId, callback);
14496 }
14497 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014498
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014499 private int stopUserLocked(final int userId, final IStopUserCallback callback) {
14500 if (mCurrentUserId == userId) {
14501 return ActivityManager.USER_OP_IS_CURRENT;
14502 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014503
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014504 final UserStartedState uss = mStartedUsers.get(userId);
14505 if (uss == null) {
14506 // User is not started, nothing to do... but we do need to
14507 // callback if requested.
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014508 if (callback != null) {
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014509 mHandler.post(new Runnable() {
14510 @Override
14511 public void run() {
14512 try {
14513 callback.userStopped(userId);
14514 } catch (RemoteException e) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014515 }
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014516 }
14517 });
14518 }
14519 return ActivityManager.USER_OP_SUCCESS;
14520 }
14521
14522 if (callback != null) {
14523 uss.mStopCallbacks.add(callback);
14524 }
14525
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014526 if (uss.mState != UserStartedState.STATE_STOPPING
14527 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014528 uss.mState = UserStartedState.STATE_STOPPING;
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014529 updateStartedUserArrayLocked();
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014530
14531 long ident = Binder.clearCallingIdentity();
14532 try {
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014533 // We are going to broadcast ACTION_USER_STOPPING and then
Dianne Hackborn40e9f292012-11-27 19:12:23 -080014534 // once that is done send a final ACTION_SHUTDOWN and then
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014535 // stop the user.
14536 final Intent stoppingIntent = new Intent(Intent.ACTION_USER_STOPPING);
14537 stoppingIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
14538 stoppingIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
14539 final Intent shutdownIntent = new Intent(Intent.ACTION_SHUTDOWN);
14540 // This is the result receiver for the final shutdown broadcast.
14541 final IIntentReceiver shutdownReceiver = new IIntentReceiver.Stub() {
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014542 @Override
14543 public void performReceive(Intent intent, int resultCode, String data,
14544 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14545 finishUserStop(uss);
14546 }
14547 };
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014548 // This is the result receiver for the initial stopping broadcast.
14549 final IIntentReceiver stoppingReceiver = new IIntentReceiver.Stub() {
14550 @Override
14551 public void performReceive(Intent intent, int resultCode, String data,
14552 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
14553 // On to the next.
14554 synchronized (ActivityManagerService.this) {
14555 if (uss.mState != UserStartedState.STATE_STOPPING) {
14556 // Whoops, we are being started back up. Abort, abort!
14557 return;
14558 }
14559 uss.mState = UserStartedState.STATE_SHUTDOWN;
14560 }
14561 broadcastIntentLocked(null, null, shutdownIntent,
14562 null, shutdownReceiver, 0, null, null, null,
14563 true, false, MY_PID, Process.SYSTEM_UID, userId);
14564 }
14565 };
14566 // Kick things off.
14567 broadcastIntentLocked(null, null, stoppingIntent,
14568 null, stoppingReceiver, 0, null, null,
14569 android.Manifest.permission.INTERACT_ACROSS_USERS,
14570 true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014571 } finally {
14572 Binder.restoreCallingIdentity(ident);
Amith Yamasani13593602012-03-22 16:16:17 -070014573 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014574 }
Amith Yamasani13593602012-03-22 16:16:17 -070014575
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014576 return ActivityManager.USER_OP_SUCCESS;
14577 }
14578
14579 void finishUserStop(UserStartedState uss) {
14580 final int userId = uss.mHandle.getIdentifier();
14581 boolean stopped;
14582 ArrayList<IStopUserCallback> callbacks;
14583 synchronized (this) {
14584 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014585 if (mStartedUsers.get(userId) != uss) {
14586 stopped = false;
14587 } else if (uss.mState != UserStartedState.STATE_SHUTDOWN) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014588 stopped = false;
14589 } else {
14590 stopped = true;
14591 // User can no longer run.
14592 mStartedUsers.remove(userId);
Dianne Hackbornbb1aeff2012-09-18 15:48:21 -070014593 mUserLru.remove(Integer.valueOf(userId));
Dianne Hackbornc72fc672012-09-20 13:12:03 -070014594 updateStartedUserArrayLocked();
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014595
14596 // Clean up all state and processes associated with the user.
14597 // Kill all the processes for the user.
14598 forceStopUserLocked(userId);
Amith Yamasani13593602012-03-22 16:16:17 -070014599 }
14600 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014601
14602 for (int i=0; i<callbacks.size(); i++) {
14603 try {
14604 if (stopped) callbacks.get(i).userStopped(userId);
14605 else callbacks.get(i).userStopAborted(userId);
14606 } catch (RemoteException e) {
14607 }
14608 }
14609 }
14610
14611 @Override
14612 public UserInfo getCurrentUser() {
Jeff Sharkey27bd34d2012-09-16 12:49:00 -070014613 if ((checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14614 != PackageManager.PERMISSION_GRANTED) && (
14615 checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14616 != PackageManager.PERMISSION_GRANTED)) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014617 String msg = "Permission Denial: getCurrentUser() from pid="
14618 + Binder.getCallingPid()
14619 + ", uid=" + Binder.getCallingUid()
Jeff Sharkey27bd34d2012-09-16 12:49:00 -070014620 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014621 Slog.w(TAG, msg);
14622 throw new SecurityException(msg);
14623 }
14624 synchronized (this) {
Dianne Hackborn1676c852012-09-10 14:52:30 -070014625 return getUserManagerLocked().getUserInfo(mCurrentUserId);
Dianne Hackborn80a4af22012-08-27 19:18:31 -070014626 }
Amith Yamasani13593602012-03-22 16:16:17 -070014627 }
14628
Dianne Hackborn50cdf7c32012-09-23 17:08:57 -070014629 int getCurrentUserIdLocked() {
14630 return mCurrentUserId;
14631 }
14632
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -070014633 @Override
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014634 public boolean isUserRunning(int userId, boolean orStopped) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -070014635 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14636 != PackageManager.PERMISSION_GRANTED) {
14637 String msg = "Permission Denial: isUserRunning() from pid="
14638 + Binder.getCallingPid()
14639 + ", uid=" + Binder.getCallingUid()
14640 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14641 Slog.w(TAG, msg);
14642 throw new SecurityException(msg);
14643 }
14644 synchronized (this) {
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014645 return isUserRunningLocked(userId, orStopped);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -070014646 }
14647 }
14648
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014649 boolean isUserRunningLocked(int userId, boolean orStopped) {
Dianne Hackborn1676c852012-09-10 14:52:30 -070014650 UserStartedState state = mStartedUsers.get(userId);
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014651 if (state == null) {
14652 return false;
14653 }
14654 if (orStopped) {
14655 return true;
14656 }
14657 return state.mState != UserStartedState.STATE_STOPPING
Dianne Hackborn36d337a2012-10-08 14:33:47 -070014658 && state.mState != UserStartedState.STATE_SHUTDOWN;
Amith Yamasani258848d2012-08-10 17:06:33 -070014659 }
Amith Yamasani742a6712011-05-04 14:49:28 -070014660
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014661 @Override
Dianne Hackbornc72fc672012-09-20 13:12:03 -070014662 public int[] getRunningUserIds() {
14663 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
14664 != PackageManager.PERMISSION_GRANTED) {
14665 String msg = "Permission Denial: isUserRunning() from pid="
14666 + Binder.getCallingPid()
14667 + ", uid=" + Binder.getCallingUid()
14668 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS;
14669 Slog.w(TAG, msg);
14670 throw new SecurityException(msg);
14671 }
14672 synchronized (this) {
14673 return mStartedUserArray;
14674 }
14675 }
14676
14677 private void updateStartedUserArrayLocked() {
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014678 int num = 0;
Dianne Hackbornc72fc672012-09-20 13:12:03 -070014679 for (int i=0; i<mStartedUsers.size(); i++) {
Dianne Hackborna8a9bd62012-10-09 15:36:59 -070014680 UserStartedState uss = mStartedUsers.valueAt(i);
14681 // This list does not include stopping users.
14682 if (uss.mState != UserStartedState.STATE_STOPPING
14683 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14684 num++;
14685 }
14686 }
14687 mStartedUserArray = new int[num];
14688 num = 0;
14689 for (int i=0; i<mStartedUsers.size(); i++) {
14690 UserStartedState uss = mStartedUsers.valueAt(i);
14691 if (uss.mState != UserStartedState.STATE_STOPPING
14692 && uss.mState != UserStartedState.STATE_SHUTDOWN) {
14693 mStartedUserArray[num] = mStartedUsers.keyAt(i);
14694 num++;
14695 }
Dianne Hackbornc72fc672012-09-20 13:12:03 -070014696 }
14697 }
14698
14699 @Override
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070014700 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
14701 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
14702 != PackageManager.PERMISSION_GRANTED) {
14703 String msg = "Permission Denial: registerUserSwitchObserver() from pid="
14704 + Binder.getCallingPid()
14705 + ", uid=" + Binder.getCallingUid()
14706 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
14707 Slog.w(TAG, msg);
14708 throw new SecurityException(msg);
14709 }
14710
14711 mUserSwitchObservers.register(observer);
14712 }
14713
14714 @Override
14715 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
14716 mUserSwitchObservers.unregister(observer);
14717 }
14718
Dianne Hackborn1676c852012-09-10 14:52:30 -070014719 private boolean userExists(int userId) {
14720 if (userId == 0) {
14721 return true;
14722 }
14723 UserManagerService ums = getUserManagerLocked();
14724 return ums != null ? (ums.getUserInfo(userId) != null) : false;
14725 }
14726
14727 int[] getUsersLocked() {
14728 UserManagerService ums = getUserManagerLocked();
14729 return ums != null ? ums.getUserIds() : new int[] { 0 };
14730 }
14731
14732 UserManagerService getUserManagerLocked() {
Amith Yamasani258848d2012-08-10 17:06:33 -070014733 if (mUserManager == null) {
Dianne Hackborn1676c852012-09-10 14:52:30 -070014734 IBinder b = ServiceManager.getService(Context.USER_SERVICE);
14735 mUserManager = (UserManagerService)IUserManager.Stub.asInterface(b);
Amith Yamasani258848d2012-08-10 17:06:33 -070014736 }
14737 return mUserManager;
Amith Yamasani742a6712011-05-04 14:49:28 -070014738 }
14739
Amith Yamasani37ce3a82012-02-06 12:04:42 -080014740 private void checkValidCaller(int uid, int userId) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070014741 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080014742
14743 throw new SecurityException("Caller uid=" + uid
14744 + " is not privileged to communicate with user=" + userId);
14745 }
Amith Yamasani742a6712011-05-04 14:49:28 -070014746
14747 private int applyUserId(int uid, int userId) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070014748 return UserHandle.getUid(userId, uid);
Amith Yamasani742a6712011-05-04 14:49:28 -070014749 }
14750
Dianne Hackborn599db5c2012-08-03 19:28:48 -070014751 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080014752 if (info == null) return null;
Amith Yamasani742a6712011-05-04 14:49:28 -070014753 ApplicationInfo newInfo = new ApplicationInfo(info);
14754 newInfo.uid = applyUserId(info.uid, userId);
Amith Yamasania4a54e22012-04-16 15:44:19 -070014755 newInfo.dataDir = USER_DATA_DIR + userId + "/"
14756 + info.packageName;
Amith Yamasani742a6712011-05-04 14:49:28 -070014757 return newInfo;
14758 }
14759
14760 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
Amith Yamasania4a54e22012-04-16 15:44:19 -070014761 if (aInfo == null
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070014762 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
Amith Yamasani742a6712011-05-04 14:49:28 -070014763 return aInfo;
14764 }
14765
14766 ActivityInfo info = new ActivityInfo(aInfo);
14767 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
14768 return info;
14769 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080014770}