blob: 3c379d173cd1dfa0613aedb57de396ac4be19396 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006-2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
Jeff Sharkey110a6b62012-03-12 11:12:41 -070019import static android.content.pm.PackageManager.PERMISSION_GRANTED;
20
Dianne Hackborn860755f2010-06-03 18:47:52 -070021import com.android.internal.R;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborn45ce8642011-07-14 16:10:16 -070023import com.android.internal.os.ProcessStats;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070024import com.android.server.AttributeCache;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import com.android.server.IntentResolver;
26import com.android.server.ProcessMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import com.android.server.SystemServer;
28import com.android.server.Watchdog;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070029import com.android.server.am.ActivityStack.ActivityState;
Dianne Hackborna924dc0d2011-02-17 14:22:17 -080030import com.android.server.wm.WindowManagerService;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031
Dianne Hackborndd71fc82009-12-16 19:24:32 -080032import dalvik.system.Zygote;
33
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.app.Activity;
35import android.app.ActivityManager;
36import android.app.ActivityManagerNative;
Dianne Hackborn8078d8c2012-03-20 11:11:26 -070037import android.app.ActivityOptions;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.app.ActivityThread;
39import android.app.AlertDialog;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070040import android.app.AppGlobals;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020041import android.app.ApplicationErrorReport;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.app.Dialog;
Dianne Hackbornb06ea702009-07-13 13:07:51 -070043import android.app.IActivityController;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.app.IApplicationThread;
45import android.app.IInstrumentationWatcher;
Dianne Hackborn860755f2010-06-03 18:47:52 -070046import android.app.INotificationManager;
Jeff Sharkeya4620792011-05-20 15:29:23 -070047import android.app.IProcessObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080048import android.app.IServiceConnection;
Dianne Hackborn80a4af22012-08-27 19:18:31 -070049import android.app.IStopUserCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.app.IThumbnailReceiver;
51import android.app.Instrumentation;
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070052import android.app.Notification;
Dianne Hackborn860755f2010-06-03 18:47:52 -070053import android.app.NotificationManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.app.PendingIntent;
Christopher Tate45281862010-03-05 15:46:30 -080055import android.app.backup.IBackupManager;
Jacek Surazskif5b9c722009-05-18 12:09:59 +020056import android.content.ActivityNotFoundException;
Dianne Hackborn21f1bd12010-02-19 17:02:21 -080057import android.content.BroadcastReceiver;
Dianne Hackborn21c241e2012-03-08 13:57:23 -080058import android.content.ClipData;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070059import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060import android.content.ComponentName;
Jeff Sharkey110a6b62012-03-12 11:12:41 -070061import android.content.ContentProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.content.ContentResolver;
63import android.content.Context;
Christian Mehlmauer7664e202010-07-20 08:46:17 +020064import android.content.DialogInterface;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070065import android.content.IContentProvider;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070066import android.content.IIntentReceiver;
67import android.content.IIntentSender;
Adam Powelldd8fab22012-03-22 17:47:27 -070068import android.content.Intent;
69import android.content.IntentFilter;
Dianne Hackbornfa82f222009-09-17 15:14:12 -070070import android.content.IntentSender;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.content.pm.ActivityInfo;
72import android.content.pm.ApplicationInfo;
73import android.content.pm.ConfigurationInfo;
74import android.content.pm.IPackageDataObserver;
75import android.content.pm.IPackageManager;
76import android.content.pm.InstrumentationInfo;
Dan Egnor66c40e72010-01-26 16:23:11 -080077import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.content.pm.PackageManager;
Amith Yamasani258848d2012-08-10 17:06:33 -070079import android.content.pm.UserInfo;
Adam Powelldd8fab22012-03-22 17:47:27 -070080import android.content.pm.PackageManager.NameNotFoundException;
Dianne Hackborn2af632f2009-07-08 14:56:37 -070081import android.content.pm.PathPermission;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.content.pm.ProviderInfo;
83import android.content.pm.ResolveInfo;
84import android.content.pm.ServiceInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040085import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.content.res.Configuration;
87import android.graphics.Bitmap;
Robert Greenwalt434203a2010-10-11 16:00:27 -070088import android.net.Proxy;
89import android.net.ProxyProperties;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090import android.net.Uri;
91import android.os.Binder;
Dan Egnor60d87622009-12-16 16:32:58 -080092import android.os.Build;
Dan Egnor42471dd2010-01-07 17:25:22 -080093import android.os.Bundle;
Dianne Hackborn3025ef32009-08-31 21:31:47 -070094import android.os.Debug;
Dan Egnor60d87622009-12-16 16:32:58 -080095import android.os.DropBoxManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import android.os.Environment;
Dan Egnor42471dd2010-01-07 17:25:22 -080097import android.os.FileObserver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import android.os.FileUtils;
99import android.os.Handler;
100import android.os.IBinder;
101import android.os.IPermissionController;
102import android.os.Looper;
103import android.os.Message;
104import android.os.Parcel;
105import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import android.os.Process;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700107import android.os.RemoteCallbackList;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108import android.os.RemoteException;
rpcraigec7ed14c2012-07-25 13:10:37 -0400109import android.os.SELinux;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110import android.os.ServiceManager;
Brad Fitzpatrick46d42382010-06-11 13:57:58 -0700111import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112import android.os.SystemClock;
113import android.os.SystemProperties;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -0700114import android.os.UserHandle;
Amith Yamasani258848d2012-08-10 17:06:33 -0700115import android.os.UserManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800116import android.provider.Settings;
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700117import android.text.format.Time;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118import android.util.EventLog;
Joe Onorato5d3bea62010-03-01 13:44:29 -0800119import android.util.Log;
Adam Powelldd8fab22012-03-22 17:47:27 -0700120import android.util.Pair;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121import android.util.PrintWriterPrinter;
Adam Powelldd8fab22012-03-22 17:47:27 -0700122import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123import android.util.SparseArray;
Amith Yamasani742a6712011-05-04 14:49:28 -0700124import android.util.SparseIntArray;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -0700125import android.util.TimeUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126import android.view.Gravity;
127import android.view.LayoutInflater;
128import android.view.View;
129import android.view.WindowManager;
130import android.view.WindowManagerPolicy;
131
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700132import java.io.BufferedInputStream;
133import java.io.BufferedOutputStream;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700134import java.io.BufferedReader;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700135import java.io.DataInputStream;
136import java.io.DataOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137import java.io.File;
138import java.io.FileDescriptor;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700139import java.io.FileInputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800140import java.io.FileNotFoundException;
Dianne Hackborncef65ee2010-09-30 18:27:22 -0700141import java.io.FileOutputStream;
Jacek Surazskif5b9c722009-05-18 12:09:59 +0200142import java.io.IOException;
Dan Egnora455d192010-03-12 08:52:28 -0800143import java.io.InputStreamReader;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144import java.io.PrintWriter;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700145import java.io.StringWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146import java.lang.ref.WeakReference;
147import java.util.ArrayList;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700148import java.util.Collections;
149import java.util.Comparator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150import java.util.HashMap;
151import java.util.HashSet;
152import java.util.Iterator;
153import java.util.List;
154import java.util.Locale;
155import java.util.Map;
Amith Yamasani13593602012-03-22 16:16:17 -0700156import java.util.Map.Entry;
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -0700157import java.util.Set;
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700158import java.util.concurrent.atomic.AtomicBoolean;
159import java.util.concurrent.atomic.AtomicLong;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700161public final class ActivityManagerService extends ActivityManagerNative
162 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
Amith Yamasani742a6712011-05-04 14:49:28 -0700163 private static final String USER_DATA_DIR = "/data/user/";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 static final String TAG = "ActivityManager";
Amith Yamasani742a6712011-05-04 14:49:28 -0700165 static final String TAG_MU = "ActivityManagerServiceMU";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800166 static final boolean DEBUG = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400167 static final boolean localLOGV = DEBUG;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800168 static final boolean DEBUG_SWITCH = localLOGV || false;
169 static final boolean DEBUG_TASKS = localLOGV || false;
170 static final boolean DEBUG_PAUSE = localLOGV || false;
171 static final boolean DEBUG_OOM_ADJ = localLOGV || false;
172 static final boolean DEBUG_TRANSITION = localLOGV || false;
173 static final boolean DEBUG_BROADCAST = localLOGV || false;
Christopher Tatef46723b2012-01-26 14:19:24 -0800174 static final boolean DEBUG_BACKGROUND_BROADCAST = DEBUG_BROADCAST || false;
Dianne Hackborn82f3f002009-06-16 18:49:05 -0700175 static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800176 static final boolean DEBUG_SERVICE = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700177 static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 static final boolean DEBUG_VISBILITY = localLOGV || false;
179 static final boolean DEBUG_PROCESSES = localLOGV || false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700180 static final boolean DEBUG_PROCESS_OBSERVERS = localLOGV || false;
Dianne Hackborna1e989b2009-09-01 19:54:29 -0700181 static final boolean DEBUG_PROVIDER = localLOGV || false;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800182 static final boolean DEBUG_URI_PERMISSION = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 static final boolean DEBUG_USER_LEAVING = localLOGV || false;
The Android Open Source Project10592532009-03-18 17:39:46 -0700184 static final boolean DEBUG_RESULTS = localLOGV || false;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -0700185 static final boolean DEBUG_BACKUP = localLOGV || false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700186 static final boolean DEBUG_CONFIGURATION = localLOGV || false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700187 static final boolean DEBUG_POWER = localLOGV || false;
188 static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
Amith Yamasani742a6712011-05-04 14:49:28 -0700189 static final boolean DEBUG_MU = localLOGV || false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190 static final boolean VALIDATE_TOKENS = false;
191 static final boolean SHOW_ACTIVITY_START_TIME = true;
192
193 // Control over CPU and battery monitoring.
194 static final long BATTERY_STATS_TIME = 30*60*1000; // write battery stats every 30 minutes.
195 static final boolean MONITOR_CPU_USAGE = true;
196 static final long MONITOR_CPU_MIN_TIME = 5*1000; // don't sample cpu less than every 5 seconds.
197 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff; // wait possibly forever for next cpu sample.
198 static final boolean MONITOR_THREAD_CPU_USAGE = false;
199
Dianne Hackborn1655be42009-05-08 14:29:01 -0700200 // The flags that are set for all calls we make to the package manager.
Dianne Hackborn11b822d2009-07-21 20:03:02 -0700201 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
Dianne Hackborn1655be42009-05-08 14:29:01 -0700202
Dianne Hackbornf02e57b2011-03-01 22:21:04 -0800203 private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800204
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -0700205 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
206
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 // Maximum number of recent tasks that we can remember.
208 static final int MAX_RECENT_TASKS = 20;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700209
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700210 // Amount of time after a call to stopAppSwitches() during which we will
211 // prevent further untrusted switches from happening.
212 static final long APP_SWITCH_DELAY_TIME = 5*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800213
214 // How long we wait for a launched process to attach to the activity manager
215 // before we decide it's never going to come up for real.
216 static final int PROC_START_TIMEOUT = 10*1000;
217
Jeff Brown3f9dd282011-07-08 20:02:19 -0700218 // How long we wait for a launched process to attach to the activity manager
219 // before we decide it's never going to come up for real, when the process was
220 // started with a wrapper for instrumentation (such as Valgrind) because it
221 // could take much longer than usual.
222 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000;
223
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800224 // How long to wait after going idle before forcing apps to GC.
225 static final int GC_TIMEOUT = 5*1000;
226
Dianne Hackbornfd12af42009-08-27 00:44:33 -0700227 // The minimum amount of time between successive GC requests for a process.
228 static final int GC_MIN_INTERVAL = 60*1000;
229
Dianne Hackborn287952c2010-09-22 22:34:31 -0700230 // The rate at which we check for apps using excessive power -- 15 mins.
231 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
232
233 // The minimum sample duration we will allow before deciding we have
234 // enough data on wake locks to start killing things.
235 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
236
237 // The minimum sample duration we will allow before deciding we have
238 // enough data on CPU usage to start killing things.
239 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 // How long we allow a receiver to run before giving up on it.
Christopher Tatef46723b2012-01-26 14:19:24 -0800242 static final int BROADCAST_FG_TIMEOUT = 10*1000;
243 static final int BROADCAST_BG_TIMEOUT = 60*1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800245 // How long we wait until we timeout on key dispatching.
246 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
247
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 // How long we wait until we timeout on key dispatching during instrumentation.
249 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
250
Dan Egnor42471dd2010-01-07 17:25:22 -0800251 static final int MY_PID = Process.myPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800252
253 static final String[] EMPTY_STRING_ARRAY = new String[0];
254
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700255 public ActivityStack mMainStack;
Mike Lockwood3a74bd32011-08-12 13:55:22 -0700256
257 private final boolean mHeadless;
258
Joe Onorato54a4a412011-11-02 20:50:08 -0700259 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
260 // default actuion automatically. Important for devices without direct input
261 // devices.
262 private boolean mShowDialogs = true;
263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800264 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700265 * Description of a request to start a new activity, which has been held
266 * due to app switches being disabled.
267 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700268 static class PendingActivityLaunch {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700269 ActivityRecord r;
270 ActivityRecord sourceRecord;
Dianne Hackborna4972e92012-03-14 10:38:05 -0700271 int startFlags;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700272 }
273
274 final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
275 = new ArrayList<PendingActivityLaunch>();
276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800278 BroadcastQueue mFgBroadcastQueue;
279 BroadcastQueue mBgBroadcastQueue;
Christopher Tatef46723b2012-01-26 14:19:24 -0800280 // Convenient for easy iteration over the queues. Foreground is first
281 // so that dispatch of foreground broadcasts gets precedence.
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800282 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
Christopher Tatef46723b2012-01-26 14:19:24 -0800283
284 BroadcastQueue broadcastQueueForIntent(Intent intent) {
285 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
286 if (DEBUG_BACKGROUND_BROADCAST) {
287 Slog.i(TAG, "Broadcast intent " + intent + " on "
288 + (isFg ? "foreground" : "background")
289 + " queue");
290 }
291 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
292 }
293
294 BroadcastRecord broadcastRecordForReceiverLocked(IBinder receiver) {
295 for (BroadcastQueue queue : mBroadcastQueues) {
296 BroadcastRecord r = queue.getMatchingOrderedReceiver(receiver);
297 if (r != null) {
298 return r;
299 }
300 }
301 return null;
302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303
304 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 * Activity we have told the window manager to have key focus.
306 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700307 ActivityRecord mFocusedActivity = null;
Dianne Hackbornbfe319e2009-09-21 00:34:05 -0700308 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309 * List of intents that were used to start the most recent tasks.
310 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700311 final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800312
313 /**
Dianne Hackborn7d608422011-08-07 16:24:18 -0700314 * Process management.
315 */
316 final ProcessList mProcessList = new ProcessList();
317
318 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 * All of the applications we currently have running organized by name.
320 * The keys are strings of the application package name (as
321 * returned by the package manager), and the keys are ApplicationRecord
322 * objects.
323 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700324 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325
326 /**
Dianne Hackborna0c283e2012-02-09 10:47:01 -0800327 * The currently running isolated processes.
328 */
329 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
330
331 /**
332 * Counter for assigning isolated process uids, to avoid frequently reusing the
333 * same ones.
334 */
335 int mNextIsolatedProcessUid = 0;
336
337 /**
Dianne Hackborn860755f2010-06-03 18:47:52 -0700338 * The currently running heavy-weight process, if any.
339 */
340 ProcessRecord mHeavyWeightProcess = null;
341
342 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 * The last time that various processes have crashed.
344 */
345 final ProcessMap<Long> mProcessCrashTimes = new ProcessMap<Long>();
346
347 /**
348 * Set of applications that we consider to be bad, and will reject
349 * incoming broadcasts from (which the user has no control over).
350 * Processes are added to this set when they have crashed twice within
351 * a minimum amount of time; they are removed from it when they are
352 * later restarted (hopefully due to some user action). The value is the
353 * time it was added to the list.
354 */
355 final ProcessMap<Long> mBadProcesses = new ProcessMap<Long>();
356
357 /**
358 * All of the processes we currently have running organized by pid.
359 * The keys are the pid running the application.
360 *
361 * <p>NOTE: This object is protected by its own lock, NOT the global
362 * activity manager lock!
363 */
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700364 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365
366 /**
367 * All of the processes that have been forced to be foreground. The key
368 * is the pid of the caller who requested it (we hold a death
369 * link on it).
370 */
371 abstract class ForegroundToken implements IBinder.DeathRecipient {
372 int pid;
373 IBinder token;
374 }
375 final SparseArray<ForegroundToken> mForegroundProcesses
376 = new SparseArray<ForegroundToken>();
377
378 /**
379 * List of records for processes that someone had tried to start before the
380 * system was ready. We don't start them at that point, but ensure they
381 * are started by the time booting is complete.
382 */
383 final ArrayList<ProcessRecord> mProcessesOnHold
384 = new ArrayList<ProcessRecord>();
385
386 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 * List of persistent applications that are in the process
388 * of being started.
389 */
390 final ArrayList<ProcessRecord> mPersistentStartingProcesses
391 = new ArrayList<ProcessRecord>();
392
393 /**
394 * Processes that are being forcibly torn down.
395 */
396 final ArrayList<ProcessRecord> mRemovedProcesses
397 = new ArrayList<ProcessRecord>();
398
399 /**
400 * List of running applications, sorted by recent usage.
401 * The first entry in the list is the least recently used.
402 * It contains ApplicationRecord objects. This list does NOT include
403 * any persistent application records (since we never want to exit them).
404 */
Dianne Hackborndd71fc82009-12-16 19:24:32 -0800405 final ArrayList<ProcessRecord> mLruProcesses
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 = new ArrayList<ProcessRecord>();
407
408 /**
409 * List of processes that should gc as soon as things are idle.
410 */
411 final ArrayList<ProcessRecord> mProcessesToGc
412 = new ArrayList<ProcessRecord>();
413
414 /**
The Android Open Source Project4df24232009-03-05 14:34:35 -0800415 * This is the process holding what we currently consider to be
416 * the "home" activity.
417 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -0700418 ProcessRecord mHomeProcess;
The Android Open Source Project4df24232009-03-05 14:34:35 -0800419
420 /**
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700421 * This is the process holding the activity the user last visited that
422 * is in a different process from the one they are currently in.
423 */
424 ProcessRecord mPreviousProcess;
Dianne Hackborn50685602011-12-01 12:23:37 -0800425
426 /**
427 * The time at which the previous process was last visible.
428 */
429 long mPreviousProcessVisibleTime;
430
Dianne Hackbornf35fe232011-11-01 19:25:20 -0700431 /**
Dianne Hackborn80a4af22012-08-27 19:18:31 -0700432 * Which uses have been started, so are allowed to run code.
433 */
434 final SparseArray<UserStartedState> mStartedUsers = new SparseArray<UserStartedState>();
435
436 /**
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400437 * Packages that the user has asked to have run in screen size
438 * compatibility mode instead of filling the screen.
439 */
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -0700440 final CompatModePackages mCompatModePackages;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400441
442 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800443 * Set of PendingResultRecord objects that are currently active.
444 */
445 final HashSet mPendingResultRecords = new HashSet();
446
447 /**
448 * Set of IntentSenderRecord objects that are currently active.
449 */
450 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
451 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
452
453 /**
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -0800454 * Fingerprints (hashCode()) of stack traces that we've
Brad Fitzpatrick143666f2010-06-14 12:40:21 -0700455 * already logged DropBox entries for. Guarded by itself. If
456 * something (rogue user app) forces this over
457 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
458 */
459 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
460 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
461
462 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -0700463 * Strict Mode background batched logging state.
464 *
465 * The string buffer is guarded by itself, and its lock is also
466 * used to determine if another batched write is already
467 * in-flight.
468 */
469 private final StringBuilder mStrictModeBuffer = new StringBuilder();
470
471 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 * Keeps track of all IIntentReceivers that have been registered for
473 * broadcasts. Hash keys are the receiver IBinder, hash value is
474 * a ReceiverList.
475 */
476 final HashMap mRegisteredReceivers = new HashMap();
477
478 /**
479 * Resolver for broadcast intents to registered receivers.
480 * Holds BroadcastFilter (subclass of IntentFilter).
481 */
482 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
483 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
484 @Override
485 protected boolean allowFilterResult(
486 BroadcastFilter filter, List<BroadcastFilter> dest) {
487 IBinder target = filter.receiverList.receiver.asBinder();
488 for (int i=dest.size()-1; i>=0; i--) {
489 if (dest.get(i).receiverList.receiver.asBinder() == target) {
490 return false;
491 }
492 }
493 return true;
494 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700495
496 @Override
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700497 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
Dianne Hackborn20e80982012-08-31 19:00:44 -0700498 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
499 || userId == filter.owningUserId) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700500 return super.newResult(filter, match, userId);
501 }
502 return null;
503 }
504
505 @Override
Dianne Hackborn9ec6cdd2012-05-31 10:57:54 -0700506 protected BroadcastFilter[] newArray(int size) {
507 return new BroadcastFilter[size];
508 }
509
510 @Override
Dianne Hackborn6c418d52011-06-29 14:05:33 -0700511 protected String packageForFilter(BroadcastFilter filter) {
512 return filter.packageName;
513 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800514 };
515
516 /**
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700517 * State of all active sticky broadcasts per user. Keys are the action of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 * sticky Intent, values are an ArrayList of all broadcasted intents with
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700519 * that action (which should usually be one). The SparseArray is keyed
520 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
521 * for stickies that are sent to all users.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800522 */
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700523 final SparseArray<HashMap<String, ArrayList<Intent>>> mStickyBroadcasts =
524 new SparseArray<HashMap<String, ArrayList<Intent>>>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800525
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700526 final ActiveServices mServices;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800527
528 /**
Christopher Tate181fafa2009-05-14 11:12:14 -0700529 * Backup/restore process management
530 */
531 String mBackupAppName = null;
532 BackupRecord mBackupTarget = null;
533
534 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 * List of PendingThumbnailsRecord objects of clients who are still
536 * waiting to receive all of the thumbnails for a task.
537 */
538 final ArrayList mPendingThumbnails = new ArrayList();
539
540 /**
541 * List of HistoryRecord objects that have been finished and must
542 * still report back to a pending thumbnail receiver.
543 */
544 final ArrayList mCancelledThumbnails = new ArrayList();
545
Amith Yamasani742a6712011-05-04 14:49:28 -0700546 final ProviderMap mProviderMap = new ProviderMap();
547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800548 /**
549 * List of content providers who have clients waiting for them. The
550 * application is currently being launched and the provider will be
551 * removed from this list once it is published.
552 */
Dianne Hackborn860755f2010-06-03 18:47:52 -0700553 final ArrayList<ContentProviderRecord> mLaunchingProviders
554 = new ArrayList<ContentProviderRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800555
556 /**
557 * Global set of specific Uri permissions that have been granted.
558 */
559 final private SparseArray<HashMap<Uri, UriPermission>> mGrantedUriPermissions
560 = new SparseArray<HashMap<Uri, UriPermission>>();
561
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800562 CoreSettingsObserver mCoreSettingsObserver;
563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 /**
565 * Thread-local storage used to carry caller permissions over through
566 * indirect content-provider access.
567 * @see #ActivityManagerService.openContentUri()
568 */
569 private class Identity {
570 public int pid;
571 public int uid;
572
573 Identity(int _pid, int _uid) {
574 pid = _pid;
575 uid = _uid;
576 }
577 }
Amith Yamasani742a6712011-05-04 14:49:28 -0700578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 private static ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
580
581 /**
582 * All information we have collected about the runtime performance of
583 * any user id that can impact battery performance.
584 */
585 final BatteryStatsService mBatteryStatsService;
586
587 /**
588 * information about component usage
589 */
590 final UsageStatsService mUsageStatsService;
591
592 /**
593 * Current configuration information. HistoryRecord objects are given
594 * a reference to this object to indicate which configuration they are
595 * currently running in, so this object must be kept immutable.
596 */
597 Configuration mConfiguration = new Configuration();
598
599 /**
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800600 * Current sequencing integer of the configuration, for skipping old
601 * configurations.
602 */
603 int mConfigurationSeq = 0;
604
605 /**
Jack Palevichb90d28c2009-07-22 15:35:24 -0700606 * Hardware-reported OpenGLES version.
607 */
608 final int GL_ES_VERSION;
609
610 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 * List of initialization arguments to pass to all processes when binding applications to them.
612 * For example, references to the commonly used services.
613 */
614 HashMap<String, IBinder> mAppBindArgs;
615
616 /**
Dianne Hackbornf210d6b2009-04-13 18:42:49 -0700617 * Temporary to avoid allocations. Protected by main lock.
618 */
619 final StringBuilder mStringBuilder = new StringBuilder(256);
620
621 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 * Used to control how we initialize the service.
623 */
624 boolean mStartRunning = false;
625 ComponentName mTopComponent;
626 String mTopAction;
627 String mTopData;
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700628 boolean mProcessesReady = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 boolean mSystemReady = false;
630 boolean mBooting = false;
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700631 boolean mWaitingUpdate = false;
632 boolean mDidUpdate = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700633 boolean mOnBattery = false;
Dianne Hackborn0dad3642010-09-09 21:25:35 -0700634 boolean mLaunchWarningShown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635
636 Context mContext;
637
638 int mFactoryTest;
639
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -0700640 boolean mCheckedForSetup;
641
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800642 /**
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700643 * The time at which we will allow normal application switches again,
644 * after a call to {@link #stopAppSwitches()}.
645 */
646 long mAppSwitchesAllowedTime;
647
648 /**
649 * This is set to true after the first switch after mAppSwitchesAllowedTime
650 * is set; any switches after that will clear the time.
651 */
652 boolean mDidAppSwitch;
653
654 /**
Dianne Hackborn287952c2010-09-22 22:34:31 -0700655 * Last time (in realtime) at which we checked for power usage.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700656 */
Dianne Hackborn287952c2010-09-22 22:34:31 -0700657 long mLastPowerCheckRealtime;
658
659 /**
660 * Last time (in uptime) at which we checked for power usage.
661 */
662 long mLastPowerCheckUptime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700663
664 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800665 * Set while we are wanting to sleep, to prevent any
666 * activities from being started/resumed.
667 */
668 boolean mSleeping = false;
669
670 /**
Dianne Hackbornff5b1582012-04-12 17:24:07 -0700671 * State of external calls telling us if the device is asleep.
672 */
673 boolean mWentToSleep = false;
674
675 /**
676 * State of external call telling us if the lock screen is shown.
677 */
678 boolean mLockScreenShown = false;
679
680 /**
Dianne Hackborn55280a92009-05-07 15:53:46 -0700681 * Set if we are shutting down the system, similar to sleeping.
682 */
683 boolean mShuttingDown = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684
685 /**
686 * Task identifier that activities are currently being started
687 * in. Incremented each time a new task is created.
688 * todo: Replace this with a TokenSpace class that generates non-repeating
689 * integers that won't wrap.
690 */
691 int mCurTask = 1;
692
693 /**
694 * Current sequence id for oom_adj computation traversal.
695 */
696 int mAdjSeq = 0;
697
698 /**
Dianne Hackborn906497c2010-05-10 15:57:38 -0700699 * Current sequence id for process LRU updating.
700 */
701 int mLruSeq = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800702
703 /**
Dianne Hackbornee7621c2012-08-13 16:42:18 -0700704 * Keep track of the non-hidden/empty process we last found, to help
705 * determine how to distribute hidden/empty processes next time.
706 */
707 int mNumNonHiddenProcs = 0;
708
709 /**
710 * Keep track of the number of hidden procs, to balance oom adj
711 * distribution between those and empty procs.
712 */
713 int mNumHiddenProcs = 0;
714
715 /**
Dianne Hackborne02c88a2011-10-28 13:58:15 -0700716 * Keep track of the number of service processes we last found, to
717 * determine on the next iteration which should be B services.
718 */
719 int mNumServiceProcs = 0;
720 int mNewNumServiceProcs = 0;
721
722 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 * System monitoring: number of processes that died since the last
724 * N procs were started.
725 */
726 int[] mProcDeaths = new int[20];
727
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700728 /**
729 * This is set if we had to do a delayed dexopt of an app before launching
730 * it, to increasing the ANR timeouts in that case.
731 */
732 boolean mDidDexOpt;
733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 String mDebugApp = null;
735 boolean mWaitForDebugger = false;
736 boolean mDebugTransient = false;
737 String mOrigDebugApp = null;
738 boolean mOrigWaitForDebugger = false;
739 boolean mAlwaysFinishActivities = false;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700740 IActivityController mController = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700741 String mProfileApp = null;
742 ProcessRecord mProfileProc = null;
743 String mProfileFile;
744 ParcelFileDescriptor mProfileFd;
745 int mProfileType = 0;
746 boolean mAutoStopProfiler = false;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800747 String mOpenGlTraceApp = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700749 static class ProcessChangeItem {
750 static final int CHANGE_ACTIVITIES = 1<<0;
751 static final int CHANGE_IMPORTANCE= 1<<1;
752 int changes;
753 int uid;
754 int pid;
755 int importance;
756 boolean foregroundActivities;
757 }
758
Jeff Sharkeya4620792011-05-20 15:29:23 -0700759 final RemoteCallbackList<IProcessObserver> mProcessObservers
760 = new RemoteCallbackList<IProcessObserver>();
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700761 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
762
763 final ArrayList<ProcessChangeItem> mPendingProcessChanges
764 = new ArrayList<ProcessChangeItem>();
765 final ArrayList<ProcessChangeItem> mAvailProcessChanges
766 = new ArrayList<ProcessChangeItem>();
Jeff Sharkeya4620792011-05-20 15:29:23 -0700767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 /**
769 * Callback of last caller to {@link #requestPss}.
770 */
771 Runnable mRequestPssCallback;
772
773 /**
774 * Remaining processes for which we are waiting results from the last
775 * call to {@link #requestPss}.
776 */
777 final ArrayList<ProcessRecord> mRequestPssList
778 = new ArrayList<ProcessRecord>();
779
780 /**
781 * Runtime statistics collection thread. This object's lock is used to
782 * protect all related state.
783 */
784 final Thread mProcessStatsThread;
785
786 /**
787 * Used to collect process stats when showing not responding dialog.
788 * Protected by mProcessStatsThread.
789 */
790 final ProcessStats mProcessStats = new ProcessStats(
791 MONITOR_THREAD_CPU_USAGE);
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -0700792 final AtomicLong mLastCpuTime = new AtomicLong(0);
793 final AtomicBoolean mProcessStatsMutexFree = new AtomicBoolean(true);
794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 long mLastWriteTime = 0;
796
797 /**
798 * Set to true after the system has finished booting.
799 */
800 boolean mBooted = false;
801
Dianne Hackborn7d608422011-08-07 16:24:18 -0700802 int mProcessLimit = ProcessList.MAX_HIDDEN_APPS;
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700803 int mProcessLimitOverride = -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800804
805 WindowManagerService mWindowManager;
806
807 static ActivityManagerService mSelf;
808 static ActivityThread mSystemThread;
809
Amith Yamasani258848d2012-08-10 17:06:33 -0700810 private int mCurrentUserId;
Amith Yamasani258848d2012-08-10 17:06:33 -0700811 private UserManager mUserManager;
812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 private final class AppDeathRecipient implements IBinder.DeathRecipient {
814 final ProcessRecord mApp;
815 final int mPid;
816 final IApplicationThread mAppThread;
817
818 AppDeathRecipient(ProcessRecord app, int pid,
819 IApplicationThread thread) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800821 TAG, "New death recipient " + this
822 + " for thread " + thread.asBinder());
823 mApp = app;
824 mPid = pid;
825 mAppThread = thread;
826 }
827
828 public void binderDied() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800829 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 TAG, "Death received in " + this
831 + " for thread " + mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 synchronized(ActivityManagerService.this) {
833 appDiedLocked(mApp, mPid, mAppThread);
834 }
835 }
836 }
837
838 static final int SHOW_ERROR_MSG = 1;
839 static final int SHOW_NOT_RESPONDING_MSG = 2;
840 static final int SHOW_FACTORY_ERROR_MSG = 3;
841 static final int UPDATE_CONFIGURATION_MSG = 4;
842 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
843 static final int WAIT_FOR_DEBUGGER_MSG = 6;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 static final int SERVICE_TIMEOUT_MSG = 12;
845 static final int UPDATE_TIME_ZONE = 13;
846 static final int SHOW_UID_ERROR_MSG = 14;
847 static final int IM_FEELING_LUCKY_MSG = 15;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800848 static final int PROC_START_TIMEOUT_MSG = 20;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700849 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -0700850 static final int KILL_APPLICATION_MSG = 22;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800851 static final int FINALIZE_PENDING_INTENT_MSG = 23;
Dianne Hackborn860755f2010-06-03 18:47:52 -0700852 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
853 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700854 static final int SHOW_STRICT_MODE_VIOLATION_MSG = 26;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700855 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700856 static final int CLEAR_DNS_CACHE = 28;
Robert Greenwalt434203a2010-10-11 16:00:27 -0700857 static final int UPDATE_HTTP_PROXY = 29;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700858 static final int SHOW_COMPAT_MODE_DIALOG_MSG = 30;
Dianne Hackborna93c2c12012-05-31 15:29:36 -0700859 static final int DISPATCH_PROCESSES_CHANGED = 31;
Dianne Hackborn36f80f32011-05-31 18:26:45 -0700860 static final int DISPATCH_PROCESS_DIED = 32;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700861 static final int REPORT_MEM_USAGE = 33;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800862
Dianne Hackborn40c8db52012-02-10 18:59:48 -0800863 static final int FIRST_ACTIVITY_STACK_MSG = 100;
864 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
865 static final int FIRST_COMPAT_MODE_MSG = 300;
866
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800867 AlertDialog mUidAlert;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -0700868 CompatModeDialog mCompatModeDialog;
Dianne Hackborn04d6db32011-11-04 20:07:24 -0700869 long mLastMemUsageReportTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800870
871 final Handler mHandler = new Handler() {
872 //public Handler() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800873 // if (localLOGV) Slog.v(TAG, "Handler started!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 //}
875
876 public void handleMessage(Message msg) {
877 switch (msg.what) {
878 case SHOW_ERROR_MSG: {
879 HashMap data = (HashMap) msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800880 synchronized (ActivityManagerService.this) {
881 ProcessRecord proc = (ProcessRecord)data.get("app");
882 if (proc != null && proc.crashDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800883 Slog.e(TAG, "App already has crash dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884 return;
885 }
886 AppErrorResult res = (AppErrorResult) data.get("result");
Joe Onorato54a4a412011-11-02 20:50:08 -0700887 if (mShowDialogs && !mSleeping && !mShuttingDown) {
Dan Egnorb7f03672009-12-09 16:22:32 -0800888 Dialog d = new AppErrorDialog(mContext, res, proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800889 d.show();
890 proc.crashDialog = d;
891 } else {
892 // The device is asleep, so just pretend that the user
893 // saw a crash dialog and hit "force quit".
894 res.set(0);
895 }
896 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700897
898 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 } break;
900 case SHOW_NOT_RESPONDING_MSG: {
901 synchronized (ActivityManagerService.this) {
902 HashMap data = (HashMap) msg.obj;
903 ProcessRecord proc = (ProcessRecord)data.get("app");
904 if (proc != null && proc.anrDialog != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800905 Slog.e(TAG, "App already has anr dialog: " + proc);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 return;
907 }
The Android Open Source Project4df24232009-03-05 14:34:35 -0800908
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700909 Intent intent = new Intent("android.intent.action.ANR");
910 if (!mProcessesReady) {
Christopher Tatef46723b2012-01-26 14:19:24 -0800911 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
912 | Intent.FLAG_RECEIVER_FOREGROUND);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -0700913 }
914 broadcastIntentLocked(null, null, intent,
The Android Open Source Project4df24232009-03-05 14:34:35 -0800915 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -0700916 false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);
The Android Open Source Project4df24232009-03-05 14:34:35 -0800917
Justin Kohbc52ca22012-03-29 15:11:44 -0700918 if (mShowDialogs) {
919 Dialog d = new AppNotRespondingDialog(ActivityManagerService.this,
Mike Lockwood69ccdbd2012-04-03 11:53:47 -0700920 mContext, proc, (ActivityRecord)data.get("activity"));
Justin Kohbc52ca22012-03-29 15:11:44 -0700921 d.show();
922 proc.anrDialog = d;
923 } else {
924 // Just kill the app if there is no dialog to be shown.
925 killAppAtUsersRequest(proc, null);
926 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -0700928
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700929 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 } break;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700931 case SHOW_STRICT_MODE_VIOLATION_MSG: {
932 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
933 synchronized (ActivityManagerService.this) {
934 ProcessRecord proc = (ProcessRecord) data.get("app");
935 if (proc == null) {
936 Slog.e(TAG, "App not found when showing strict mode dialog.");
937 break;
938 }
939 if (proc.crashDialog != null) {
940 Slog.e(TAG, "App already has strict mode dialog: " + proc);
941 return;
942 }
943 AppErrorResult res = (AppErrorResult) data.get("result");
Joe Onorato54a4a412011-11-02 20:50:08 -0700944 if (mShowDialogs && !mSleeping && !mShuttingDown) {
Brad Fitzpatrick438d0592010-06-10 12:19:19 -0700945 Dialog d = new StrictModeViolationDialog(mContext, res, proc);
946 d.show();
947 proc.crashDialog = d;
948 } else {
949 // The device is asleep, so just pretend that the user
950 // saw a crash dialog and hit "force quit".
951 res.set(0);
952 }
953 }
954 ensureBootCompleted();
955 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 case SHOW_FACTORY_ERROR_MSG: {
957 Dialog d = new FactoryErrorDialog(
958 mContext, msg.getData().getCharSequence("msg"));
959 d.show();
Dianne Hackborn9acc0302009-08-25 00:27:12 -0700960 ensureBootCompleted();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 } break;
962 case UPDATE_CONFIGURATION_MSG: {
963 final ContentResolver resolver = mContext.getContentResolver();
964 Settings.System.putConfiguration(resolver, (Configuration)msg.obj);
965 } break;
966 case GC_BACKGROUND_PROCESSES_MSG: {
967 synchronized (ActivityManagerService.this) {
968 performAppGcsIfAppropriateLocked();
969 }
970 } break;
971 case WAIT_FOR_DEBUGGER_MSG: {
972 synchronized (ActivityManagerService.this) {
973 ProcessRecord app = (ProcessRecord)msg.obj;
974 if (msg.arg1 != 0) {
975 if (!app.waitedForDebugger) {
976 Dialog d = new AppWaitingForDebuggerDialog(
977 ActivityManagerService.this,
978 mContext, app);
979 app.waitDialog = d;
980 app.waitedForDebugger = true;
981 d.show();
982 }
983 } else {
984 if (app.waitDialog != null) {
985 app.waitDialog.dismiss();
986 app.waitDialog = null;
987 }
988 }
989 }
990 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 case SERVICE_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700992 if (mDidDexOpt) {
993 mDidDexOpt = false;
994 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
995 nmsg.obj = msg.obj;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700996 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -0700997 return;
998 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700999 mServices.serviceTimeout((ProcessRecord)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000 } break;
1001 case UPDATE_TIME_ZONE: {
1002 synchronized (ActivityManagerService.this) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001003 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1004 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 if (r.thread != null) {
1006 try {
1007 r.thread.updateTimeZone();
1008 } catch (RemoteException ex) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001009 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 }
1011 }
1012 }
1013 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001014 } break;
Robert Greenwalt03595d02010-11-02 14:08:23 -07001015 case CLEAR_DNS_CACHE: {
1016 synchronized (ActivityManagerService.this) {
1017 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1018 ProcessRecord r = mLruProcesses.get(i);
1019 if (r.thread != null) {
1020 try {
1021 r.thread.clearDnsCache();
1022 } catch (RemoteException ex) {
1023 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1024 }
1025 }
1026 }
1027 }
1028 } break;
Robert Greenwalt434203a2010-10-11 16:00:27 -07001029 case UPDATE_HTTP_PROXY: {
1030 ProxyProperties proxy = (ProxyProperties)msg.obj;
1031 String host = "";
1032 String port = "";
1033 String exclList = "";
1034 if (proxy != null) {
1035 host = proxy.getHost();
1036 port = Integer.toString(proxy.getPort());
1037 exclList = proxy.getExclusionList();
1038 }
1039 synchronized (ActivityManagerService.this) {
1040 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1041 ProcessRecord r = mLruProcesses.get(i);
1042 if (r.thread != null) {
1043 try {
1044 r.thread.setHttpProxy(host, port, exclList);
1045 } catch (RemoteException ex) {
1046 Slog.w(TAG, "Failed to update http proxy for: " +
1047 r.info.processName);
1048 }
1049 }
1050 }
1051 }
1052 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 case SHOW_UID_ERROR_MSG: {
Joe Onorato54a4a412011-11-02 20:50:08 -07001054 String title = "System UIDs Inconsistent";
1055 String text = "UIDs on the system are inconsistent, you need to wipe your"
1056 + " data partition or your device will be unstable.";
1057 Log.e(TAG, title + ": " + text);
1058 if (mShowDialogs) {
1059 // XXX This is a temporary dialog, no need to localize.
1060 AlertDialog d = new BaseErrorDialog(mContext);
1061 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1062 d.setCancelable(false);
1063 d.setTitle(title);
1064 d.setMessage(text);
1065 d.setButton(DialogInterface.BUTTON_POSITIVE, "I'm Feeling Lucky",
1066 mHandler.obtainMessage(IM_FEELING_LUCKY_MSG));
1067 mUidAlert = d;
1068 d.show();
1069 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001070 } break;
1071 case IM_FEELING_LUCKY_MSG: {
1072 if (mUidAlert != null) {
1073 mUidAlert.dismiss();
1074 mUidAlert = null;
1075 }
1076 } break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001077 case PROC_START_TIMEOUT_MSG: {
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001078 if (mDidDexOpt) {
1079 mDidDexOpt = false;
1080 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1081 nmsg.obj = msg.obj;
1082 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1083 return;
1084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001085 ProcessRecord app = (ProcessRecord)msg.obj;
1086 synchronized (ActivityManagerService.this) {
1087 processStartTimedOutLocked(app);
1088 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001089 } break;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07001090 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1091 synchronized (ActivityManagerService.this) {
1092 doPendingActivityLaunchesLocked(true);
1093 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07001094 } break;
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001095 case KILL_APPLICATION_MSG: {
1096 synchronized (ActivityManagerService.this) {
1097 int uid = msg.arg1;
1098 boolean restart = (msg.arg2 == 1);
1099 String pkg = (String) msg.obj;
Amith Yamasani483f3b02012-03-13 16:08:00 -07001100 forceStopPackageLocked(pkg, uid, restart, false, true, false,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001101 UserHandle.getUserId(uid));
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07001102 }
1103 } break;
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001104 case FINALIZE_PENDING_INTENT_MSG: {
1105 ((PendingIntentRecord)msg.obj).completeFinalize();
1106 } break;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001107 case POST_HEAVY_NOTIFICATION_MSG: {
1108 INotificationManager inm = NotificationManager.getService();
1109 if (inm == null) {
1110 return;
1111 }
1112
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001113 ActivityRecord root = (ActivityRecord)msg.obj;
Dianne Hackborn860755f2010-06-03 18:47:52 -07001114 ProcessRecord process = root.app;
1115 if (process == null) {
1116 return;
1117 }
1118
1119 try {
1120 Context context = mContext.createPackageContext(process.info.packageName, 0);
1121 String text = mContext.getString(R.string.heavy_weight_notification,
1122 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1123 Notification notification = new Notification();
1124 notification.icon = com.android.internal.R.drawable.stat_sys_adb; //context.getApplicationInfo().icon;
1125 notification.when = 0;
1126 notification.flags = Notification.FLAG_ONGOING_EVENT;
1127 notification.tickerText = text;
1128 notification.defaults = 0; // please be quiet
1129 notification.sound = null;
1130 notification.vibrate = null;
1131 notification.setLatestEventInfo(context, text,
1132 mContext.getText(R.string.heavy_weight_notification_detail),
Dianne Hackborn41203752012-08-31 14:05:51 -07001133 PendingIntent.getActivityAsUser(mContext, 0, root.intent,
1134 PendingIntent.FLAG_CANCEL_CURRENT, null,
1135 new UserHandle(root.userId)));
Dianne Hackborn860755f2010-06-03 18:47:52 -07001136
1137 try {
1138 int[] outId = new int[1];
Dianne Hackborn41203752012-08-31 14:05:51 -07001139 inm.enqueueNotificationWithTag("android", null,
1140 R.string.heavy_weight_notification,
1141 notification, outId, root.userId);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001142 } catch (RuntimeException e) {
1143 Slog.w(ActivityManagerService.TAG,
1144 "Error showing notification for heavy-weight app", e);
1145 } catch (RemoteException e) {
1146 }
1147 } catch (NameNotFoundException e) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07001148 Slog.w(TAG, "Unable to create context for heavy notification", e);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001149 }
1150 } break;
1151 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1152 INotificationManager inm = NotificationManager.getService();
1153 if (inm == null) {
1154 return;
1155 }
1156 try {
Dianne Hackborn41203752012-08-31 14:05:51 -07001157 inm.cancelNotificationWithTag("android", null,
1158 R.string.heavy_weight_notification, msg.arg1);
Dianne Hackborn860755f2010-06-03 18:47:52 -07001159 } catch (RuntimeException e) {
1160 Slog.w(ActivityManagerService.TAG,
1161 "Error canceling notification for service", e);
1162 } catch (RemoteException e) {
1163 }
1164 } break;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001165 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1166 synchronized (ActivityManagerService.this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001167 checkExcessivePowerUsageLocked(true);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07001168 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001169 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1170 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001171 }
1172 } break;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001173 case SHOW_COMPAT_MODE_DIALOG_MSG: {
1174 synchronized (ActivityManagerService.this) {
1175 ActivityRecord ar = (ActivityRecord)msg.obj;
1176 if (mCompatModeDialog != null) {
1177 if (mCompatModeDialog.mAppInfo.packageName.equals(
1178 ar.info.applicationInfo.packageName)) {
1179 return;
1180 }
1181 mCompatModeDialog.dismiss();
1182 mCompatModeDialog = null;
1183 }
Dianne Hackborn29478262011-06-07 15:44:22 -07001184 if (ar != null && false) {
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07001185 if (mCompatModePackages.getPackageAskCompatModeLocked(
1186 ar.packageName)) {
1187 int mode = mCompatModePackages.computeCompatModeLocked(
1188 ar.info.applicationInfo);
1189 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1190 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1191 mCompatModeDialog = new CompatModeDialog(
1192 ActivityManagerService.this, mContext,
1193 ar.info.applicationInfo);
1194 mCompatModeDialog.show();
1195 }
1196 }
1197 }
1198 }
Dianne Hackborn36f80f32011-05-31 18:26:45 -07001199 break;
1200 }
Dianne Hackborna93c2c12012-05-31 15:29:36 -07001201 case DISPATCH_PROCESSES_CHANGED: {
1202 dispatchProcessesChanged();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001203 break;
1204 }
1205 case DISPATCH_PROCESS_DIED: {
Jeff Sharkey287bd832011-05-28 19:36:26 -07001206 final int pid = msg.arg1;
1207 final int uid = msg.arg2;
1208 dispatchProcessDied(pid, uid);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001209 break;
1210 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001211 case REPORT_MEM_USAGE: {
1212 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
1213 if (!isDebuggable) {
1214 return;
1215 }
1216 synchronized (ActivityManagerService.this) {
1217 long now = SystemClock.uptimeMillis();
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001218 if (now < (mLastMemUsageReportTime+5*60*1000)) {
1219 // Don't report more than every 5 minutes to somewhat
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001220 // avoid spamming.
1221 return;
1222 }
1223 mLastMemUsageReportTime = now;
1224 }
1225 Thread thread = new Thread() {
1226 @Override public void run() {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001227 StringBuilder dropBuilder = new StringBuilder(1024);
1228 StringBuilder logBuilder = new StringBuilder(1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -08001229 StringWriter oomSw = new StringWriter();
1230 PrintWriter oomPw = new PrintWriter(oomSw);
1231 StringWriter catSw = new StringWriter();
1232 PrintWriter catPw = new PrintWriter(catSw);
1233 String[] emptyArgs = new String[] { };
1234 StringBuilder tag = new StringBuilder(128);
1235 StringBuilder stack = new StringBuilder(128);
1236 tag.append("Low on memory -- ");
1237 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw,
1238 tag, stack);
1239 dropBuilder.append(stack);
1240 dropBuilder.append('\n');
1241 dropBuilder.append('\n');
1242 String oomString = oomSw.toString();
1243 dropBuilder.append(oomString);
1244 dropBuilder.append('\n');
1245 logBuilder.append(oomString);
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001246 try {
1247 java.lang.Process proc = Runtime.getRuntime().exec(new String[] {
1248 "procrank", });
1249 final InputStreamReader converter = new InputStreamReader(
1250 proc.getInputStream());
1251 BufferedReader in = new BufferedReader(converter);
1252 String line;
1253 while (true) {
1254 line = in.readLine();
1255 if (line == null) {
1256 break;
1257 }
1258 if (line.length() > 0) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001259 logBuilder.append(line);
1260 logBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001261 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001262 dropBuilder.append(line);
1263 dropBuilder.append('\n');
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001264 }
1265 converter.close();
1266 } catch (IOException e) {
1267 }
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001268 synchronized (ActivityManagerService.this) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08001269 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001270 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001271 catPw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001272 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
1273 false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001274 catPw.println();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001275 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
Dianne Hackborn7aa6d312011-11-15 15:01:14 -08001276 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001277 dropBuilder.append(catSw.toString());
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001278 addErrorToDropBox("lowmem", null, "system_server", null,
1279 null, tag.toString(), dropBuilder.toString(), null, null);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08001280 Slog.i(TAG, logBuilder.toString());
Dianne Hackborn04d6db32011-11-04 20:07:24 -07001281 synchronized (ActivityManagerService.this) {
1282 long now = SystemClock.uptimeMillis();
1283 if (mLastMemUsageReportTime < now) {
1284 mLastMemUsageReportTime = now;
1285 }
1286 }
1287 }
1288 };
1289 thread.start();
1290 break;
1291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 }
1293 }
1294 };
1295
1296 public static void setSystemProcess() {
1297 try {
1298 ActivityManagerService m = mSelf;
1299
Dianne Hackborna573f6a2012-02-09 16:12:18 -08001300 ServiceManager.addService("activity", m, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 ServiceManager.addService("meminfo", new MemBinder(m));
Chet Haase9c1e23b2011-03-24 10:51:31 -07001302 ServiceManager.addService("gfxinfo", new GraphicsBinder(m));
Jeff Brown6754ba22011-12-14 20:20:01 -08001303 ServiceManager.addService("dbinfo", new DbBinder(m));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 if (MONITOR_CPU_USAGE) {
1305 ServiceManager.addService("cpuinfo", new CpuBinder(m));
1306 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 ServiceManager.addService("permission", new PermissionController(m));
1308
1309 ApplicationInfo info =
1310 mSelf.mContext.getPackageManager().getApplicationInfo(
Amith Yamasani483f3b02012-03-13 16:08:00 -07001311 "android", STOCK_PM_FLAGS);
Mike Cleron432b7132009-09-24 15:28:29 -07001312 mSystemThread.installSystemApplicationInfo(info);
1313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 synchronized (mSelf) {
1315 ProcessRecord app = mSelf.newProcessRecordLocked(
1316 mSystemThread.getApplicationThread(), info,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001317 info.processName, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 app.persistent = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08001319 app.pid = MY_PID;
Dianne Hackborn7d608422011-08-07 16:24:18 -07001320 app.maxAdj = ProcessList.SYSTEM_ADJ;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001321 mSelf.mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 synchronized (mSelf.mPidsSelfLocked) {
1323 mSelf.mPidsSelfLocked.put(app.pid, app);
1324 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001325 mSelf.updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 }
1327 } catch (PackageManager.NameNotFoundException e) {
1328 throw new RuntimeException(
1329 "Unable to find android system package", e);
1330 }
1331 }
1332
1333 public void setWindowManager(WindowManagerService wm) {
1334 mWindowManager = wm;
1335 }
1336
1337 public static final Context main(int factoryTest) {
1338 AThread thr = new AThread();
1339 thr.start();
1340
1341 synchronized (thr) {
1342 while (thr.mService == null) {
1343 try {
1344 thr.wait();
1345 } catch (InterruptedException e) {
1346 }
1347 }
1348 }
1349
1350 ActivityManagerService m = thr.mService;
1351 mSelf = m;
1352 ActivityThread at = ActivityThread.systemMain();
1353 mSystemThread = at;
1354 Context context = at.getSystemContext();
Dianne Hackborn247fe742011-01-08 17:25:57 -08001355 context.setTheme(android.R.style.Theme_Holo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 m.mContext = context;
1357 m.mFactoryTest = factoryTest;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001358 m.mMainStack = new ActivityStack(m, context, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359
1360 m.mBatteryStatsService.publish(context);
1361 m.mUsageStatsService.publish(context);
1362
1363 synchronized (thr) {
1364 thr.mReady = true;
1365 thr.notifyAll();
1366 }
1367
1368 m.startRunning(null, null, null, null);
1369
1370 return context;
1371 }
1372
1373 public static ActivityManagerService self() {
1374 return mSelf;
1375 }
1376
1377 static class AThread extends Thread {
1378 ActivityManagerService mService;
1379 boolean mReady = false;
1380
1381 public AThread() {
1382 super("ActivityManager");
1383 }
1384
1385 public void run() {
1386 Looper.prepare();
1387
1388 android.os.Process.setThreadPriority(
1389 android.os.Process.THREAD_PRIORITY_FOREGROUND);
Christopher Tate160edb32010-06-30 17:46:30 -07001390 android.os.Process.setCanSelfBackground(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001391
1392 ActivityManagerService m = new ActivityManagerService();
1393
1394 synchronized (this) {
1395 mService = m;
1396 notifyAll();
1397 }
1398
1399 synchronized (this) {
1400 while (!mReady) {
1401 try {
1402 wait();
1403 } catch (InterruptedException e) {
1404 }
1405 }
1406 }
1407
Brad Fitzpatrickec062f62010-11-03 09:56:54 -07001408 // For debug builds, log event loop stalls to dropbox for analysis.
1409 if (StrictMode.conditionallyEnableDebugLogging()) {
1410 Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
1411 }
1412
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 Looper.loop();
1414 }
1415 }
1416
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 static class MemBinder extends Binder {
1418 ActivityManagerService mActivityManagerService;
1419 MemBinder(ActivityManagerService activityManagerService) {
1420 mActivityManagerService = activityManagerService;
1421 }
1422
1423 @Override
1424 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001425 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1426 != PackageManager.PERMISSION_GRANTED) {
1427 pw.println("Permission Denial: can't dump meminfo from from pid="
1428 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1429 + " without permission " + android.Manifest.permission.DUMP);
1430 return;
1431 }
1432
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -08001433 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args,
Dianne Hackborn672342c2011-11-29 11:29:02 -08001434 false, null, null, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 }
1436 }
1437
Chet Haase9c1e23b2011-03-24 10:51:31 -07001438 static class GraphicsBinder extends Binder {
1439 ActivityManagerService mActivityManagerService;
1440 GraphicsBinder(ActivityManagerService activityManagerService) {
1441 mActivityManagerService = activityManagerService;
1442 }
1443
1444 @Override
1445 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001446 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1447 != PackageManager.PERMISSION_GRANTED) {
1448 pw.println("Permission Denial: can't dump gfxinfo from from pid="
1449 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1450 + " without permission " + android.Manifest.permission.DUMP);
1451 return;
1452 }
1453
Dianne Hackborne17aeb32011-04-07 15:11:57 -07001454 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
Chet Haase9c1e23b2011-03-24 10:51:31 -07001455 }
1456 }
1457
Jeff Brown6754ba22011-12-14 20:20:01 -08001458 static class DbBinder extends Binder {
1459 ActivityManagerService mActivityManagerService;
1460 DbBinder(ActivityManagerService activityManagerService) {
1461 mActivityManagerService = activityManagerService;
1462 }
1463
1464 @Override
1465 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1466 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1467 != PackageManager.PERMISSION_GRANTED) {
1468 pw.println("Permission Denial: can't dump dbinfo from from pid="
1469 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1470 + " without permission " + android.Manifest.permission.DUMP);
1471 return;
1472 }
1473
1474 mActivityManagerService.dumpDbInfo(fd, pw, args);
1475 }
1476 }
1477
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 static class CpuBinder extends Binder {
1479 ActivityManagerService mActivityManagerService;
1480 CpuBinder(ActivityManagerService activityManagerService) {
1481 mActivityManagerService = activityManagerService;
1482 }
1483
1484 @Override
1485 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Kenny Root3abd75b2011-09-29 11:00:41 -07001486 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
1487 != PackageManager.PERMISSION_GRANTED) {
1488 pw.println("Permission Denial: can't dump cpuinfo from from pid="
1489 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
1490 + " without permission " + android.Manifest.permission.DUMP);
1491 return;
1492 }
1493
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 synchronized (mActivityManagerService.mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07001495 pw.print(mActivityManagerService.mProcessStats.printCurrentLoad());
1496 pw.print(mActivityManagerService.mProcessStats.printCurrentState(
1497 SystemClock.uptimeMillis()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001498 }
1499 }
1500 }
1501
1502 private ActivityManagerService() {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001503 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
Dianne Hackborn2c6c5e62009-10-08 17:55:49 -07001504
Dianne Hackborn40c8db52012-02-10 18:59:48 -08001505 mFgBroadcastQueue = new BroadcastQueue(this, "foreground", BROADCAST_FG_TIMEOUT);
1506 mBgBroadcastQueue = new BroadcastQueue(this, "background", BROADCAST_BG_TIMEOUT);
1507 mBroadcastQueues[0] = mFgBroadcastQueue;
1508 mBroadcastQueues[1] = mBgBroadcastQueue;
1509
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001510 mServices = new ActiveServices(this);
1511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 File dataDir = Environment.getDataDirectory();
1513 File systemDir = new File(dataDir, "system");
1514 systemDir.mkdirs();
1515 mBatteryStatsService = new BatteryStatsService(new File(
1516 systemDir, "batterystats.bin").toString());
1517 mBatteryStatsService.getActiveStatistics().readLocked();
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001518 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
Dianne Hackborn287952c2010-09-22 22:34:31 -07001519 mOnBattery = DEBUG_POWER ? true
1520 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001521 mBatteryStatsService.getActiveStatistics().setCallback(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001522
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001523 mUsageStatsService = new UsageStatsService(new File(
Dianne Hackborn6447ca32009-04-07 19:50:08 -07001524 systemDir, "usagestats").toString());
Mike Lockwood3a74bd32011-08-12 13:55:22 -07001525 mHeadless = "1".equals(SystemProperties.get("ro.config.headless", "0"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001526
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001527 // User 0 is the first and only user that runs at boot.
1528 mStartedUsers.put(0, new UserStartedState(new UserHandle(0), true));
1529
Jack Palevichb90d28c2009-07-22 15:35:24 -07001530 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
1531 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
1532
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08001533 mConfiguration.setToDefaults();
1534 mConfiguration.locale = Locale.getDefault();
Dianne Hackborn813075a62011-11-14 17:45:19 -08001535 mConfigurationSeq = mConfiguration.seq = 1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 mProcessStats.init();
1537
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07001538 mCompatModePackages = new CompatModePackages(this, systemDir);
1539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 // Add ourself to the Watchdog monitors.
1541 Watchdog.getInstance().addMonitor(this);
1542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 mProcessStatsThread = new Thread("ProcessStats") {
1544 public void run() {
1545 while (true) {
1546 try {
1547 try {
1548 synchronized(this) {
1549 final long now = SystemClock.uptimeMillis();
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001550 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
Joe Onorato8a9b2202010-02-26 18:56:32 -08001552 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001553 // + ", write delay=" + nextWriteDelay);
1554 if (nextWriteDelay < nextCpuDelay) {
1555 nextCpuDelay = nextWriteDelay;
1556 }
1557 if (nextCpuDelay > 0) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001558 mProcessStatsMutexFree.set(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 this.wait(nextCpuDelay);
1560 }
1561 }
1562 } catch (InterruptedException e) {
1563 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001564 updateCpuStatsNow();
1565 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001566 Slog.e(TAG, "Unexpected exception collecting process stats", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 }
1568 }
1569 }
1570 };
1571 mProcessStatsThread.start();
1572 }
1573
1574 @Override
1575 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
1576 throws RemoteException {
Dianne Hackborna53de062012-05-08 18:53:51 -07001577 if (code == SYSPROPS_TRANSACTION) {
1578 // We need to tell all apps about the system property change.
1579 ArrayList<IBinder> procs = new ArrayList<IBinder>();
1580 synchronized(this) {
1581 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
1582 final int NA = apps.size();
1583 for (int ia=0; ia<NA; ia++) {
1584 ProcessRecord app = apps.valueAt(ia);
1585 if (app.thread != null) {
1586 procs.add(app.thread.asBinder());
1587 }
1588 }
1589 }
1590 }
1591
1592 int N = procs.size();
1593 for (int i=0; i<N; i++) {
1594 Parcel data2 = Parcel.obtain();
1595 try {
1596 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
1597 } catch (RemoteException e) {
1598 }
1599 data2.recycle();
1600 }
1601 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001602 try {
1603 return super.onTransact(code, data, reply, flags);
1604 } catch (RuntimeException e) {
1605 // The activity manager only throws security exceptions, so let's
1606 // log all others.
1607 if (!(e instanceof SecurityException)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08001608 Slog.e(TAG, "Activity Manager Crash", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 }
1610 throw e;
1611 }
1612 }
1613
1614 void updateCpuStats() {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001615 final long now = SystemClock.uptimeMillis();
1616 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
1617 return;
1618 }
1619 if (mProcessStatsMutexFree.compareAndSet(true, false)) {
1620 synchronized (mProcessStatsThread) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 mProcessStatsThread.notify();
1622 }
1623 }
1624 }
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001625
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001626 void updateCpuStatsNow() {
1627 synchronized (mProcessStatsThread) {
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001628 mProcessStatsMutexFree.set(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 final long now = SystemClock.uptimeMillis();
1630 boolean haveNewCpuStats = false;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07001631
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001632 if (MONITOR_CPU_USAGE &&
Brad Fitzpatrick01fad4a2010-04-19 10:47:40 -07001633 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
1634 mLastCpuTime.set(now);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 haveNewCpuStats = true;
1636 mProcessStats.update();
Joe Onorato8a9b2202010-02-26 18:56:32 -08001637 //Slog.i(TAG, mProcessStats.printCurrentState());
1638 //Slog.i(TAG, "Total CPU usage: "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 // + mProcessStats.getTotalCpuPercent() + "%");
1640
Joe Onorato8a9b2202010-02-26 18:56:32 -08001641 // Slog the cpu usage if the property is set.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001642 if ("true".equals(SystemProperties.get("events.cpu"))) {
1643 int user = mProcessStats.getLastUserTime();
1644 int system = mProcessStats.getLastSystemTime();
1645 int iowait = mProcessStats.getLastIoWaitTime();
1646 int irq = mProcessStats.getLastIrqTime();
1647 int softIrq = mProcessStats.getLastSoftIrqTime();
1648 int idle = mProcessStats.getLastIdleTime();
1649
1650 int total = user + system + iowait + irq + softIrq + idle;
1651 if (total == 0) total = 1;
1652
Doug Zongker2bec3d42009-12-04 12:52:44 -08001653 EventLog.writeEvent(EventLogTags.CPU,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 ((user+system+iowait+irq+softIrq) * 100) / total,
1655 (user * 100) / total,
1656 (system * 100) / total,
1657 (iowait * 100) / total,
1658 (irq * 100) / total,
1659 (softIrq * 100) / total);
1660 }
1661 }
1662
Amith Yamasanie43530a2009-08-21 13:11:37 -07001663 long[] cpuSpeedTimes = mProcessStats.getLastCpuSpeedTimes();
Amith Yamasani819f9282009-06-24 23:18:15 -07001664 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001665 synchronized(bstats) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001666 synchronized(mPidsSelfLocked) {
1667 if (haveNewCpuStats) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001668 if (mOnBattery) {
1669 int perc = bstats.startAddingCpuLocked();
1670 int totalUTime = 0;
1671 int totalSTime = 0;
Dianne Hackborn287952c2010-09-22 22:34:31 -07001672 final int N = mProcessStats.countStats();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001674 ProcessStats.Stats st = mProcessStats.getStats(i);
1675 if (!st.working) {
1676 continue;
1677 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001679 int otherUTime = (st.rel_utime*perc)/100;
1680 int otherSTime = (st.rel_stime*perc)/100;
1681 totalUTime += otherUTime;
1682 totalSTime += otherSTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001683 if (pr != null) {
1684 BatteryStatsImpl.Uid.Proc ps = pr.batteryStats;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001685 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1686 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001687 ps.addSpeedStepTimes(cpuSpeedTimes);
Dianne Hackborn287952c2010-09-22 22:34:31 -07001688 pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001689 } else {
1690 BatteryStatsImpl.Uid.Proc ps =
Amith Yamasani819f9282009-06-24 23:18:15 -07001691 bstats.getProcessStatsLocked(st.name, st.pid);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001692 if (ps != null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001693 ps.addCpuTimeLocked(st.rel_utime-otherUTime,
1694 st.rel_stime-otherSTime);
Amith Yamasanie43530a2009-08-21 13:11:37 -07001695 ps.addSpeedStepTimes(cpuSpeedTimes);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001697 }
1698 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001699 bstats.finishAddingCpuLocked(perc, totalUTime,
1700 totalSTime, cpuSpeedTimes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 }
1702 }
1703 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001705 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
1706 mLastWriteTime = now;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07001707 mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001708 }
1709 }
1710 }
1711 }
1712
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001713 @Override
1714 public void batteryNeedsCpuUpdate() {
1715 updateCpuStatsNow();
1716 }
1717
1718 @Override
1719 public void batteryPowerChanged(boolean onBattery) {
1720 // When plugging in, update the CPU stats first before changing
1721 // the plug state.
1722 updateCpuStatsNow();
1723 synchronized (this) {
1724 synchronized(mPidsSelfLocked) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001725 mOnBattery = DEBUG_POWER ? true : onBattery;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001726 }
1727 }
1728 }
1729
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001730 /**
1731 * Initialize the application bind args. These are passed to each
1732 * process when the bindApplication() IPC is sent to the process. They're
1733 * lazily setup to make sure the services are running when they're asked for.
1734 */
1735 private HashMap<String, IBinder> getCommonServicesLocked() {
1736 if (mAppBindArgs == null) {
1737 mAppBindArgs = new HashMap<String, IBinder>();
1738
1739 // Setup the application init args
1740 mAppBindArgs.put("package", ServiceManager.getService("package"));
1741 mAppBindArgs.put("window", ServiceManager.getService("window"));
1742 mAppBindArgs.put(Context.ALARM_SERVICE,
1743 ServiceManager.getService(Context.ALARM_SERVICE));
1744 }
1745 return mAppBindArgs;
1746 }
1747
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001748 final void setFocusedActivityLocked(ActivityRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 if (mFocusedActivity != r) {
1750 mFocusedActivity = r;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08001751 if (r != null) {
1752 mWindowManager.setFocusedApp(r.appToken, true);
1753 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754 }
1755 }
1756
Dianne Hackborn906497c2010-05-10 15:57:38 -07001757 private final void updateLruProcessInternalLocked(ProcessRecord app,
1758 boolean oomAdj, boolean updateActivityTime, int bestPos) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001759 // put it on the LRU to keep track of when it should be exited.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001760 int lrui = mLruProcesses.indexOf(app);
1761 if (lrui >= 0) mLruProcesses.remove(lrui);
1762
1763 int i = mLruProcesses.size()-1;
1764 int skipTop = 0;
1765
Dianne Hackborn906497c2010-05-10 15:57:38 -07001766 app.lruSeq = mLruSeq;
1767
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001768 // compute the new weight for this process.
1769 if (updateActivityTime) {
1770 app.lastActivityTime = SystemClock.uptimeMillis();
1771 }
1772 if (app.activities.size() > 0) {
1773 // If this process has activities, we more strongly want to keep
1774 // it around.
1775 app.lruWeight = app.lastActivityTime;
1776 } else if (app.pubProviders.size() > 0) {
1777 // If this process contains content providers, we want to keep
1778 // it a little more strongly.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001779 app.lruWeight = app.lastActivityTime - ProcessList.CONTENT_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001780 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001781 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001782 } else {
1783 // If this process doesn't have activities, we less strongly
1784 // want to keep it around, and generally want to avoid getting
1785 // in front of any very recently used activities.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001786 app.lruWeight = app.lastActivityTime - ProcessList.EMPTY_APP_IDLE_OFFSET;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001787 // Also don't let it kick out the first few "real" hidden processes.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001788 skipTop = ProcessList.MIN_HIDDEN_APPS;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001789 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001790
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001791 while (i >= 0) {
1792 ProcessRecord p = mLruProcesses.get(i);
1793 // If this app shouldn't be in front of the first N background
1794 // apps, then skip over that many that are currently hidden.
Dianne Hackborn7d608422011-08-07 16:24:18 -07001795 if (skipTop > 0 && p.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001796 skipTop--;
1797 }
Dianne Hackborn906497c2010-05-10 15:57:38 -07001798 if (p.lruWeight <= app.lruWeight || i < bestPos) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08001799 mLruProcesses.add(i+1, app);
1800 break;
1801 }
1802 i--;
1803 }
1804 if (i < 0) {
1805 mLruProcesses.add(0, app);
1806 }
1807
Dianne Hackborn906497c2010-05-10 15:57:38 -07001808 // If the app is currently using a content provider or service,
1809 // bump those processes as well.
1810 if (app.connections.size() > 0) {
1811 for (ConnectionRecord cr : app.connections) {
1812 if (cr.binding != null && cr.binding.service != null
1813 && cr.binding.service.app != null
1814 && cr.binding.service.app.lruSeq != mLruSeq) {
Björn Davidsson90f9e312010-11-18 08:26:27 +01001815 updateLruProcessInternalLocked(cr.binding.service.app, false,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001816 updateActivityTime, i+1);
1817 }
1818 }
1819 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001820 for (int j=app.conProviders.size()-1; j>=0; j--) {
1821 ContentProviderRecord cpr = app.conProviders.get(j).provider;
1822 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq) {
Jean-Baptiste Querub8c64052012-06-11 11:01:19 -07001823 updateLruProcessInternalLocked(cpr.proc, false,
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001824 updateActivityTime, i+1);
Dianne Hackborn906497c2010-05-10 15:57:38 -07001825 }
1826 }
1827
Joe Onorato8a9b2202010-02-26 18:56:32 -08001828 //Slog.i(TAG, "Putting proc to front: " + app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 if (oomAdj) {
1830 updateOomAdjLocked();
1831 }
1832 }
1833
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001834 final void updateLruProcessLocked(ProcessRecord app,
Dianne Hackborn906497c2010-05-10 15:57:38 -07001835 boolean oomAdj, boolean updateActivityTime) {
1836 mLruSeq++;
1837 updateLruProcessInternalLocked(app, oomAdj, updateActivityTime, 0);
1838 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07001839
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001840 final ProcessRecord getProcessRecordLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001841 String processName, int uid) {
Amith Yamasania4a54e22012-04-16 15:44:19 -07001842 if (uid == Process.SYSTEM_UID) {
Amith Yamasani0184ce92012-03-28 22:41:41 -07001843 // The system gets to run in any process. If there are multiple
1844 // processes with the same uid, just pick the first (this
1845 // should never happen).
1846 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(
1847 processName);
Amith Yamasania4a54e22012-04-16 15:44:19 -07001848 if (procs == null) return null;
1849 final int N = procs.size();
1850 for (int i = 0; i < N; i++) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001851 if (UserHandle.isSameUser(procs.keyAt(i), uid)) return procs.valueAt(i);
Amith Yamasania4a54e22012-04-16 15:44:19 -07001852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 }
1854 ProcessRecord proc = mProcessNames.get(processName, uid);
1855 return proc;
1856 }
1857
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001858 void ensurePackageDexOpt(String packageName) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001859 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07001860 try {
1861 if (pm.performDexOpt(packageName)) {
1862 mDidDexOpt = true;
1863 }
1864 } catch (RemoteException e) {
1865 }
1866 }
1867
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001868 boolean isNextTransitionForward() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001869 int transit = mWindowManager.getPendingAppTransition();
1870 return transit == WindowManagerPolicy.TRANSIT_ACTIVITY_OPEN
1871 || transit == WindowManagerPolicy.TRANSIT_TASK_OPEN
1872 || transit == WindowManagerPolicy.TRANSIT_TASK_TO_FRONT;
1873 }
1874
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07001875 final ProcessRecord startProcessLocked(String processName,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001877 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
1878 boolean isolated) {
1879 ProcessRecord app;
1880 if (!isolated) {
1881 app = getProcessRecordLocked(processName, info.uid);
1882 } else {
1883 // If this is an isolated process, it can't re-use an existing process.
1884 app = null;
1885 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001886 // We don't have to do anything more if:
1887 // (1) There is an existing application record; and
1888 // (2) The caller doesn't think it is dead, OR there is no thread
1889 // object attached to it so we know it couldn't have crashed; and
1890 // (3) There is a pid assigned to it, so it is either starting or
1891 // already running.
Joe Onorato8a9b2202010-02-26 18:56:32 -08001892 if (DEBUG_PROCESSES) Slog.v(TAG, "startProcess: name=" + processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001893 + " app=" + app + " knownToBeDead=" + knownToBeDead
1894 + " thread=" + (app != null ? app.thread : null)
1895 + " pid=" + (app != null ? app.pid : -1));
Magnus Edlund7bb25812010-02-24 15:45:06 +01001896 if (app != null && app.pid > 0) {
1897 if (!knownToBeDead || app.thread == null) {
Dianne Hackborn20cb56e2010-03-04 00:58:29 -08001898 // We already have the app running, or are waiting for it to
1899 // come up (we have a pid but not yet its thread), so keep it.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001900 if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
Dianne Hackborn6c418d52011-06-29 14:05:33 -07001901 // If this is a new package in the process, add the package to the list
1902 app.addPackage(info.packageName);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001903 return app;
1904 } else {
1905 // An application record is attached to a previous process,
1906 // clean it up now.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001907 if (DEBUG_PROCESSES) Slog.v(TAG, "App died: " + app);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07001908 handleAppDiedLocked(app, true, true);
Magnus Edlund7bb25812010-02-24 15:45:06 +01001909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001910 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01001911
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001912 String hostingNameStr = hostingName != null
1913 ? hostingName.flattenToShortString() : null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001914
1915 if (!isolated) {
1916 if ((intentFlags&Intent.FLAG_FROM_BACKGROUND) != 0) {
1917 // If we are in the background, then check to see if this process
1918 // is bad. If so, we will just silently fail.
1919 if (mBadProcesses.get(info.processName, info.uid) != null) {
1920 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
1921 + "/" + info.processName);
1922 return null;
1923 }
1924 } else {
1925 // When the user is explicitly starting a process, then clear its
1926 // crash count so that we won't make it bad until they see at
1927 // least one crash dialog again, and make the process good again
1928 // if it had been bad.
1929 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001930 + "/" + info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001931 mProcessCrashTimes.remove(info.processName, info.uid);
1932 if (mBadProcesses.get(info.processName, info.uid) != null) {
1933 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, info.uid,
1934 info.processName);
1935 mBadProcesses.remove(info.processName, info.uid);
1936 if (app != null) {
1937 app.bad = false;
1938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001939 }
1940 }
1941 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001942
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001943 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001944 app = newProcessRecordLocked(null, info, processName, isolated);
1945 if (app == null) {
1946 Slog.w(TAG, "Failed making new process record for "
1947 + processName + "/" + info.uid + " isolated=" + isolated);
1948 return null;
1949 }
1950 mProcessNames.put(processName, app.uid, app);
1951 if (isolated) {
1952 mIsolatedProcesses.put(app.uid, app);
1953 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001954 } else {
1955 // If this is a new package in the process, add the package to the list
1956 app.addPackage(info.packageName);
1957 }
1958
1959 // If the system is not ready yet, then hold off on starting this
1960 // process until it is.
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001961 if (!mProcessesReady
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001962 && !isAllowedWhileBooting(info)
1963 && !allowWhileBooting) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 if (!mProcessesOnHold.contains(app)) {
1965 mProcessesOnHold.add(app);
1966 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001967 if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 return app;
1969 }
1970
1971 startProcessLocked(app, hostingType, hostingNameStr);
1972 return (app.pid != 0) ? app : null;
1973 }
1974
Dianne Hackborn9acc0302009-08-25 00:27:12 -07001975 boolean isAllowedWhileBooting(ApplicationInfo ai) {
1976 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
1977 }
1978
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979 private final void startProcessLocked(ProcessRecord app,
1980 String hostingType, String hostingNameStr) {
1981 if (app.pid > 0 && app.pid != MY_PID) {
1982 synchronized (mPidsSelfLocked) {
1983 mPidsSelfLocked.remove(app.pid);
1984 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
1985 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001986 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 }
1988
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07001989 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
1990 "startProcessLocked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001991 mProcessesOnHold.remove(app);
1992
1993 updateCpuStats();
1994
1995 System.arraycopy(mProcDeaths, 0, mProcDeaths, 1, mProcDeaths.length-1);
1996 mProcDeaths[0] = 0;
1997
1998 try {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08001999 int uid = app.uid;
Amith Yamasani742a6712011-05-04 14:49:28 -07002000
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002001 int[] gids = null;
Jeff Sharkey5b1ada22012-08-14 18:47:09 -07002002 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002003 if (!app.isolated) {
2004 try {
Jeff Sharkey5b1ada22012-08-14 18:47:09 -07002005 final PackageManager pm = mContext.getPackageManager();
2006 gids = pm.getPackageGids(app.info.packageName);
Jeff Sharkeye217ee42012-08-28 16:23:01 -07002007
2008 if (Environment.isExternalStorageEmulated()) {
2009 if (pm.checkPermission(
2010 android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
2011 app.info.packageName) == PERMISSION_GRANTED) {
2012 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER_ALL;
2013 } else {
2014 mountExternal = Zygote.MOUNT_EXTERNAL_MULTIUSER;
2015 }
2016 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002017 } catch (PackageManager.NameNotFoundException e) {
2018 Slog.w(TAG, "Unable to retrieve gids", e);
2019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 }
2021 if (mFactoryTest != SystemServer.FACTORY_TEST_OFF) {
2022 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2023 && mTopComponent != null
2024 && app.processName.equals(mTopComponent.getPackageName())) {
2025 uid = 0;
2026 }
2027 if (mFactoryTest == SystemServer.FACTORY_TEST_HIGH_LEVEL
2028 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
2029 uid = 0;
2030 }
2031 }
2032 int debugFlags = 0;
2033 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
2034 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
Elliott Hughesfa36aee2011-06-17 14:39:41 -07002035 // Also turn on CheckJNI for debuggable apps. It's quite
2036 // awkward to turn on otherwise.
2037 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 }
Ben Cheng6c0afff2010-02-14 16:18:56 -08002039 // Run the app in safe mode if its manifest requests so or the
2040 // system is booted in safe mode.
2041 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
2042 Zygote.systemInSafeMode == true) {
Ben Cheng23085b72010-02-08 16:06:32 -08002043 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
2044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002045 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
2046 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
2047 }
Elliott Hughesae07ecf2011-07-06 17:33:27 -07002048 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
2049 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
2050 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051 if ("1".equals(SystemProperties.get("debug.assert"))) {
2052 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
2053 }
Jeff Brown3f9dd282011-07-08 20:02:19 -07002054
2055 // Start the process. It will either succeed and return a result containing
2056 // the PID of the new process, or else throw a RuntimeException.
2057 Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
Jeff Sharkey5b1ada22012-08-14 18:47:09 -07002058 app.processName, uid, uid, gids, debugFlags, mountExternal,
Stephen Smalley83d9eda2012-01-13 08:34:17 -05002059 app.info.targetSdkVersion, null, null);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002060
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002061 BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
2062 synchronized (bs) {
2063 if (bs.isOnBattery()) {
2064 app.batteryStats.incStartsLocked();
2065 }
2066 }
2067
Jeff Brown3f9dd282011-07-08 20:02:19 -07002068 EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002069 app.processName, hostingType,
2070 hostingNameStr != null ? hostingNameStr : "");
2071
2072 if (app.persistent) {
Jeff Brown3f9dd282011-07-08 20:02:19 -07002073 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002074 }
2075
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07002076 StringBuilder buf = mStringBuilder;
2077 buf.setLength(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002078 buf.append("Start proc ");
2079 buf.append(app.processName);
2080 buf.append(" for ");
2081 buf.append(hostingType);
2082 if (hostingNameStr != null) {
2083 buf.append(" ");
2084 buf.append(hostingNameStr);
2085 }
2086 buf.append(": pid=");
Jeff Brown3f9dd282011-07-08 20:02:19 -07002087 buf.append(startResult.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002088 buf.append(" uid=");
2089 buf.append(uid);
2090 buf.append(" gids={");
2091 if (gids != null) {
2092 for (int gi=0; gi<gids.length; gi++) {
2093 if (gi != 0) buf.append(", ");
2094 buf.append(gids[gi]);
2095
2096 }
2097 }
2098 buf.append("}");
Joe Onorato8a9b2202010-02-26 18:56:32 -08002099 Slog.i(TAG, buf.toString());
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002100 app.setPid(startResult.pid);
Jeff Brown3f9dd282011-07-08 20:02:19 -07002101 app.usingWrapper = startResult.usingWrapper;
2102 app.removed = false;
2103 synchronized (mPidsSelfLocked) {
2104 this.mPidsSelfLocked.put(startResult.pid, app);
2105 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
2106 msg.obj = app;
2107 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
2108 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 }
2110 } catch (RuntimeException e) {
2111 // XXX do better error recovery.
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002112 app.setPid(0);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002113 Slog.e(TAG, "Failure starting process " + app.processName, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 }
2115 }
2116
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002117 void updateUsageStats(ActivityRecord resumedComponent, boolean resumed) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 if (resumed) {
2119 mUsageStatsService.noteResumeComponent(resumedComponent.realActivity);
2120 } else {
2121 mUsageStatsService.notePauseComponent(resumedComponent.realActivity);
2122 }
2123 }
2124
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002125 boolean startHomeActivityLocked(int userId, UserStartedState startingUser) {
Mike Lockwooda8f767a2011-08-31 14:32:37 -04002126 if (mHeadless) {
2127 // Added because none of the other calls to ensureBootCompleted seem to fire
2128 // when running headless.
2129 ensureBootCompleted();
2130 return false;
2131 }
2132
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002133 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL
2134 && mTopAction == null) {
2135 // We are running in factory test mode, but unable to find
2136 // the factory test app, so just sit around displaying the
2137 // error message and don't try to start anything.
2138 return false;
2139 }
2140 Intent intent = new Intent(
2141 mTopAction,
2142 mTopData != null ? Uri.parse(mTopData) : null);
2143 intent.setComponent(mTopComponent);
2144 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
2145 intent.addCategory(Intent.CATEGORY_HOME);
2146 }
2147 ActivityInfo aInfo =
2148 intent.resolveActivityInfo(mContext.getPackageManager(),
2149 STOCK_PM_FLAGS);
2150 if (aInfo != null) {
2151 intent.setComponent(new ComponentName(
2152 aInfo.applicationInfo.packageName, aInfo.name));
2153 // Don't do this if the home app is currently being
2154 // instrumented.
Amith Yamasani742a6712011-05-04 14:49:28 -07002155 aInfo = new ActivityInfo(aInfo);
2156 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002157 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
2158 aInfo.applicationInfo.uid);
2159 if (app == null || app.instrumentationClass == null) {
2160 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
Dianne Hackborna4972e92012-03-14 10:38:05 -07002161 mMainStack.startActivityLocked(null, intent, null, aInfo,
2162 null, null, 0, 0, 0, 0, null, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002163 }
2164 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07002165 if (startingUser != null) {
2166 mMainStack.addStartingUserLocked(startingUser);
2167 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002168
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002169 return true;
2170 }
Amith Yamasani742a6712011-05-04 14:49:28 -07002171
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002172 /**
2173 * Starts the "new version setup screen" if appropriate.
2174 */
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002175 void startSetupActivityLocked() {
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002176 // Only do this once per boot.
2177 if (mCheckedForSetup) {
2178 return;
2179 }
2180
2181 // We will show this screen if the current one is a different
2182 // version than the last one shown, and we are not running in
2183 // low-level factory test mode.
2184 final ContentResolver resolver = mContext.getContentResolver();
2185 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL &&
2186 Settings.Secure.getInt(resolver,
2187 Settings.Secure.DEVICE_PROVISIONED, 0) != 0) {
2188 mCheckedForSetup = true;
2189
2190 // See if we should be showing the platform update setup UI.
2191 Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
2192 List<ResolveInfo> ris = mSelf.mContext.getPackageManager()
2193 .queryIntentActivities(intent, PackageManager.GET_META_DATA);
2194
2195 // We don't allow third party apps to replace this.
2196 ResolveInfo ri = null;
2197 for (int i=0; ris != null && i<ris.size(); i++) {
2198 if ((ris.get(i).activityInfo.applicationInfo.flags
2199 & ApplicationInfo.FLAG_SYSTEM) != 0) {
2200 ri = ris.get(i);
2201 break;
2202 }
2203 }
2204
2205 if (ri != null) {
2206 String vers = ri.activityInfo.metaData != null
2207 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
2208 : null;
2209 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
2210 vers = ri.activityInfo.applicationInfo.metaData.getString(
2211 Intent.METADATA_SETUP_VERSION);
2212 }
2213 String lastVers = Settings.Secure.getString(
2214 resolver, Settings.Secure.LAST_SETUP_SHOWN);
2215 if (vers != null && !vers.equals(lastVers)) {
2216 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2217 intent.setComponent(new ComponentName(
2218 ri.activityInfo.packageName, ri.activityInfo.name));
Dianne Hackborna4972e92012-03-14 10:38:05 -07002219 mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
2220 null, null, 0, 0, 0, 0, null, false, null);
Dianne Hackbornd7cd29d2009-07-01 11:22:45 -07002221 }
2222 }
2223 }
2224 }
2225
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002226 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002227 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002228 }
2229
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002230 void enforceNotIsolatedCaller(String caller) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002231 if (UserHandle.isIsolated(Binder.getCallingUid())) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002232 throw new SecurityException("Isolated process not allowed to call " + caller);
2233 }
2234 }
2235
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002236 public int getFrontActivityScreenCompatMode() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002237 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002238 synchronized (this) {
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002239 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
2240 }
2241 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002242
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002243 public void setFrontActivityScreenCompatMode(int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002244 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2245 "setFrontActivityScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002246 synchronized (this) {
2247 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
2248 }
2249 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002250
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002251 public int getPackageScreenCompatMode(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002252 enforceNotIsolatedCaller("getPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002253 synchronized (this) {
2254 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
2255 }
2256 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002257
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002258 public void setPackageScreenCompatMode(String packageName, int mode) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002259 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2260 "setPackageScreenCompatMode");
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -07002261 synchronized (this) {
2262 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002263 }
2264 }
2265
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002266 public boolean getPackageAskScreenCompat(String packageName) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002267 enforceNotIsolatedCaller("getPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002268 synchronized (this) {
2269 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
2270 }
2271 }
2272
2273 public void setPackageAskScreenCompat(String packageName, boolean ask) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002274 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
2275 "setPackageAskScreenCompat");
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07002276 synchronized (this) {
2277 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
2278 }
2279 }
2280
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002281 void reportResumedActivityLocked(ActivityRecord r) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002282 //Slog.i(TAG, "**** REPORT RESUME: " + r);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002283 updateUsageStats(r, true);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285
Dianne Hackborna93c2c12012-05-31 15:29:36 -07002286 private void dispatchProcessesChanged() {
2287 int N;
2288 synchronized (this) {
2289 N = mPendingProcessChanges.size();
2290 if (mActiveProcessChanges.length < N) {
2291 mActiveProcessChanges = new ProcessChangeItem[N];
2292 }
2293 mPendingProcessChanges.toArray(mActiveProcessChanges);
2294 mAvailProcessChanges.addAll(mPendingProcessChanges);
2295 mPendingProcessChanges.clear();
2296 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "*** Delivering " + N + " process changes");
2297 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07002298 int i = mProcessObservers.beginBroadcast();
2299 while (i > 0) {
2300 i--;
2301 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2302 if (observer != null) {
2303 try {
Dianne Hackborna93c2c12012-05-31 15:29:36 -07002304 for (int j=0; j<N; j++) {
2305 ProcessChangeItem item = mActiveProcessChanges[j];
2306 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
2307 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "ACTIVITIES CHANGED pid="
2308 + item.pid + " uid=" + item.uid + ": "
2309 + item.foregroundActivities);
2310 observer.onForegroundActivitiesChanged(item.pid, item.uid,
2311 item.foregroundActivities);
2312 }
2313 if ((item.changes&ProcessChangeItem.CHANGE_IMPORTANCE) != 0) {
2314 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "IMPORTANCE CHANGED pid="
2315 + item.pid + " uid=" + item.uid + ": " + item.importance);
2316 observer.onImportanceChanged(item.pid, item.uid,
2317 item.importance);
2318 }
2319 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07002320 } catch (RemoteException e) {
2321 }
2322 }
2323 }
2324 mProcessObservers.finishBroadcast();
2325 }
2326
2327 private void dispatchProcessDied(int pid, int uid) {
2328 int i = mProcessObservers.beginBroadcast();
2329 while (i > 0) {
2330 i--;
2331 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
2332 if (observer != null) {
2333 try {
2334 observer.onProcessDied(pid, uid);
2335 } catch (RemoteException e) {
2336 }
2337 }
2338 }
2339 mProcessObservers.finishBroadcast();
2340 }
2341
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002342 final void doPendingActivityLaunchesLocked(boolean doResume) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002343 final int N = mPendingActivityLaunches.size();
2344 if (N <= 0) {
2345 return;
2346 }
2347 for (int i=0; i<N; i++) {
2348 PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002349 mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07002350 pal.startFlags, doResume && i == (N-1), null);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07002351 }
2352 mPendingActivityLaunches.clear();
2353 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002354
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002355 public final int startActivity(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002356 Intent intent, String resolvedType, IBinder resultTo,
2357 String resultWho, int requestCode, int startFlags,
2358 String profileFile, ParcelFileDescriptor profileFd, Bundle options) {
Amith Yamasani82644082012-08-03 13:09:11 -07002359 return startActivityAsUser(caller, intent, resolvedType, resultTo, resultWho, requestCode,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002360 startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
Amith Yamasani82644082012-08-03 13:09:11 -07002361 }
2362
2363 public final int startActivityAsUser(IApplicationThread caller,
2364 Intent intent, String resolvedType, IBinder resultTo,
2365 String resultWho, int requestCode, int startFlags,
2366 String profileFile, ParcelFileDescriptor profileFd, Bundle options, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002367 enforceNotIsolatedCaller("startActivity");
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002368 if (userId != UserHandle.getCallingUserId()) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07002369 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2370 false, true, "startActivity", null);
Amith Yamasani82644082012-08-03 13:09:11 -07002371 } else {
2372 if (intent.getCategories() != null
2373 && intent.getCategories().contains(Intent.CATEGORY_HOME)) {
2374 // Requesting home, set the identity to the current user
2375 // HACK!
2376 userId = mCurrentUserId;
Amith Yamasani742a6712011-05-04 14:49:28 -07002377 }
2378 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002379 return mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002380 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
2381 null, null, options, userId);
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002382 }
2383
2384 public final WaitResult startActivityAndWait(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002385 Intent intent, String resolvedType, IBinder resultTo,
2386 String resultWho, int requestCode, int startFlags, String profileFile,
2387 ParcelFileDescriptor profileFd, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002388 enforceNotIsolatedCaller("startActivityAndWait");
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002389 WaitResult res = new WaitResult();
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002390 mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002391 resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
Dianne Hackborn41203752012-08-31 14:05:51 -07002392 res, null, options, UserHandle.getCallingUserId());
Dianne Hackborn8f7f35e2010-02-25 18:48:12 -08002393 return res;
2394 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08002395
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002396 public final int startActivityWithConfig(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002397 Intent intent, String resolvedType, IBinder resultTo,
2398 String resultWho, int requestCode, int startFlags, Configuration config,
Dianne Hackborn41203752012-08-31 14:05:51 -07002399 Bundle options, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002400 enforceNotIsolatedCaller("startActivityWithConfig");
Dianne Hackborn41203752012-08-31 14:05:51 -07002401 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2402 false, true, "startActivityWithConfig", null);
Amith Yamasani742a6712011-05-04 14:49:28 -07002403 int ret = mMainStack.startActivityMayWait(caller, -1, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002404 resultTo, resultWho, requestCode, startFlags,
Dianne Hackborn41203752012-08-31 14:05:51 -07002405 null, null, null, config, options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002406 return ret;
Dianne Hackborn2ccda4d2010-03-22 21:49:15 -07002407 }
2408
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002409 public int startActivityIntentSender(IApplicationThread caller,
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002410 IntentSender intent, Intent fillInIntent, String resolvedType,
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002411 IBinder resultTo, String resultWho, int requestCode,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002412 int flagsMask, int flagsValues, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002413 enforceNotIsolatedCaller("startActivityIntentSender");
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002414 // Refuse possible leaked file descriptors
2415 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
2416 throw new IllegalArgumentException("File descriptors passed in Intent");
2417 }
2418
2419 IIntentSender sender = intent.getTarget();
2420 if (!(sender instanceof PendingIntentRecord)) {
2421 throw new IllegalArgumentException("Bad PendingIntent object");
2422 }
2423
2424 PendingIntentRecord pir = (PendingIntentRecord)sender;
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002425
2426 synchronized (this) {
2427 // If this is coming from the currently resumed activity, it is
2428 // effectively saying that app switches are allowed at this point.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002429 if (mMainStack.mResumedActivity != null
2430 && mMainStack.mResumedActivity.info.applicationInfo.uid ==
Dianne Hackbornfa82f222009-09-17 15:14:12 -07002431 Binder.getCallingUid()) {
2432 mAppSwitchesAllowedTime = 0;
2433 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002434 }
Dianne Hackborna4972e92012-03-14 10:38:05 -07002435 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
2436 resultTo, resultWho, requestCode, flagsMask, flagsValues, options);
Amith Yamasani742a6712011-05-04 14:49:28 -07002437 return ret;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -07002438 }
2439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 public boolean startNextMatchingActivity(IBinder callingActivity,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002441 Intent intent, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002442 // Refuse possible leaked file descriptors
2443 if (intent != null && intent.hasFileDescriptors() == true) {
2444 throw new IllegalArgumentException("File descriptors passed in Intent");
2445 }
2446
2447 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002448 ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
2449 if (r == null) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002450 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 return false;
2452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002453 if (r.app == null || r.app.thread == null) {
2454 // The caller is not running... d'oh!
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002455 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 return false;
2457 }
2458 intent = new Intent(intent);
2459 // The caller is not allowed to change the data.
2460 intent.setDataAndType(r.intent.getData(), r.intent.getType());
2461 // And we are resetting to find the next component...
2462 intent.setComponent(null);
2463
2464 ActivityInfo aInfo = null;
2465 try {
2466 List<ResolveInfo> resolves =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002467 AppGlobals.getPackageManager().queryIntentActivities(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 intent, r.resolvedType,
Amith Yamasani483f3b02012-03-13 16:08:00 -07002469 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002470 UserHandle.getCallingUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002471
2472 // Look for the original activity in the list...
2473 final int N = resolves != null ? resolves.size() : 0;
2474 for (int i=0; i<N; i++) {
2475 ResolveInfo rInfo = resolves.get(i);
2476 if (rInfo.activityInfo.packageName.equals(r.packageName)
2477 && rInfo.activityInfo.name.equals(r.info.name)) {
2478 // We found the current one... the next matching is
2479 // after it.
2480 i++;
2481 if (i<N) {
2482 aInfo = resolves.get(i).activityInfo;
2483 }
2484 break;
2485 }
2486 }
2487 } catch (RemoteException e) {
2488 }
2489
2490 if (aInfo == null) {
2491 // Nobody who is next!
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07002492 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 return false;
2494 }
2495
2496 intent.setComponent(new ComponentName(
2497 aInfo.applicationInfo.packageName, aInfo.name));
2498 intent.setFlags(intent.getFlags()&~(
2499 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
2500 Intent.FLAG_ACTIVITY_CLEAR_TOP|
2501 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
2502 Intent.FLAG_ACTIVITY_NEW_TASK));
2503
2504 // Okay now we need to start the new activity, replacing the
2505 // currently running activity. This is a little tricky because
2506 // we want to start the new one as if the current one is finished,
2507 // but not finish the current one first so that there is no flicker.
2508 // And thus...
2509 final boolean wasFinishing = r.finishing;
2510 r.finishing = true;
2511
2512 // Propagate reply information over to the new activity.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002513 final ActivityRecord resultTo = r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 final String resultWho = r.resultWho;
2515 final int requestCode = r.requestCode;
2516 r.resultTo = null;
2517 if (resultTo != null) {
2518 resultTo.removeResultsLocked(r, resultWho, requestCode);
2519 }
2520
2521 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002522 int res = mMainStack.startActivityLocked(r.app.thread, intent,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002523 r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
2524 resultWho, requestCode, -1, r.launchedFromUid, 0,
2525 options, false, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 Binder.restoreCallingIdentity(origId);
2527
2528 r.finishing = wasFinishing;
Dianne Hackborna4972e92012-03-14 10:38:05 -07002529 if (res != ActivityManager.START_SUCCESS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 return false;
2531 }
2532 return true;
2533 }
2534 }
2535
Dianne Hackborn41203752012-08-31 14:05:51 -07002536 final int startActivityInPackage(int uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002537 Intent intent, String resolvedType, IBinder resultTo,
Dianne Hackborn41203752012-08-31 14:05:51 -07002538 String resultWho, int requestCode, int startFlags, Bundle options, int userId) {
2539
2540 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2541 false, true, "startActivityInPackage", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542
Amith Yamasani742a6712011-05-04 14:49:28 -07002543 int ret = mMainStack.startActivityMayWait(null, uid, intent, resolvedType,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002544 resultTo, resultWho, requestCode, startFlags,
Dianne Hackborn41203752012-08-31 14:05:51 -07002545 null, null, null, null, options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002546 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002547 }
2548
2549 public final int startActivities(IApplicationThread caller,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002550 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle options) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08002551 enforceNotIsolatedCaller("startActivities");
Amith Yamasani742a6712011-05-04 14:49:28 -07002552 int ret = mMainStack.startActivities(caller, -1, intents, resolvedTypes, resultTo,
Dianne Hackborn41203752012-08-31 14:05:51 -07002553 options, UserHandle.getCallingUserId());
Amith Yamasani742a6712011-05-04 14:49:28 -07002554 return ret;
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002555 }
2556
Dianne Hackborn41203752012-08-31 14:05:51 -07002557 final int startActivitiesInPackage(int uid,
Dianne Hackborna4972e92012-03-14 10:38:05 -07002558 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
Dianne Hackborn41203752012-08-31 14:05:51 -07002559 Bundle options, int userId) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08002560
Dianne Hackborn41203752012-08-31 14:05:51 -07002561 userId = handleIncomingUserLocked(Binder.getCallingPid(), Binder.getCallingUid(), userId,
2562 false, true, "startActivityInPackage", null);
Amith Yamasani742a6712011-05-04 14:49:28 -07002563 int ret = mMainStack.startActivities(null, uid, intents, resolvedTypes, resultTo,
Dianne Hackborn41203752012-08-31 14:05:51 -07002564 options, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07002565 return ret;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002566 }
2567
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002568 final void addRecentTaskLocked(TaskRecord task) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 int N = mRecentTasks.size();
Dianne Hackborn7c0e75e2010-12-21 19:15:40 -08002570 // Quick case: check if the top-most recent task is the same.
2571 if (N > 0 && mRecentTasks.get(0) == task) {
2572 return;
2573 }
2574 // Remove any existing entries that are the same kind of task.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002575 for (int i=0; i<N; i++) {
2576 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07002577 if (task.userId == tr.userId
2578 && ((task.affinity != null && task.affinity.equals(tr.affinity))
2579 || (task.intent != null && task.intent.filterEquals(tr.intent)))) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002580 mRecentTasks.remove(i);
2581 i--;
2582 N--;
2583 if (task.intent == null) {
2584 // If the new recent task we are adding is not fully
2585 // specified, then replace it with the existing recent task.
2586 task = tr;
2587 }
2588 }
2589 }
2590 if (N >= MAX_RECENT_TASKS) {
2591 mRecentTasks.remove(N-1);
2592 }
2593 mRecentTasks.add(0, task);
2594 }
2595
2596 public void setRequestedOrientation(IBinder token,
2597 int requestedOrientation) {
2598 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002599 ActivityRecord r = mMainStack.isInStackLocked(token);
2600 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002601 return;
2602 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002603 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornbe707852011-11-11 14:32:10 -08002604 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 Configuration config = mWindowManager.updateOrientationFromAppTokens(
The Android Open Source Project10592532009-03-18 17:39:46 -07002606 mConfiguration,
Dianne Hackbornbe707852011-11-11 14:32:10 -08002607 r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002608 if (config != null) {
2609 r.frozenBeforeDestroy = true;
Dianne Hackborn813075a62011-11-14 17:45:19 -08002610 if (!updateConfigurationLocked(config, r, false, false)) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002611 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002612 }
2613 }
2614 Binder.restoreCallingIdentity(origId);
2615 }
2616 }
2617
2618 public int getRequestedOrientation(IBinder token) {
2619 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002620 ActivityRecord r = mMainStack.isInStackLocked(token);
2621 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
2623 }
Dianne Hackbornbe707852011-11-11 14:32:10 -08002624 return mWindowManager.getAppOrientation(r.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002625 }
2626 }
2627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 /**
2629 * This is the internal entry point for handling Activity.finish().
2630 *
2631 * @param token The Binder token referencing the Activity we want to finish.
2632 * @param resultCode Result code, if any, from this Activity.
2633 * @param resultData Result data (Intent), if any, from this Activity.
2634 *
Alexey Tarasov83bad3d2009-08-12 15:05:43 +11002635 * @return Returns true if the activity successfully finished, or false if it is still running.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 */
2637 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
2638 // Refuse possible leaked file descriptors
2639 if (resultData != null && resultData.hasFileDescriptors() == true) {
2640 throw new IllegalArgumentException("File descriptors passed in Intent");
2641 }
2642
2643 synchronized(this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002644 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 // Find the first activity that is not finishing.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002646 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 if (next != null) {
2648 // ask watcher if this is allowed
2649 boolean resumeOK = true;
2650 try {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002651 resumeOK = mController.activityResuming(next.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002652 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002653 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002654 }
2655
2656 if (!resumeOK) {
2657 return false;
2658 }
2659 }
2660 }
2661 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002662 boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 resultData, "app-request");
2664 Binder.restoreCallingIdentity(origId);
2665 return res;
2666 }
2667 }
2668
Dianne Hackborn860755f2010-06-03 18:47:52 -07002669 public final void finishHeavyWeightApp() {
2670 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2671 != PackageManager.PERMISSION_GRANTED) {
2672 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
2673 + Binder.getCallingPid()
2674 + ", uid=" + Binder.getCallingUid()
2675 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2676 Slog.w(TAG, msg);
2677 throw new SecurityException(msg);
2678 }
2679
2680 synchronized(this) {
2681 if (mHeavyWeightProcess == null) {
2682 return;
2683 }
2684
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002685 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(
Dianne Hackborn860755f2010-06-03 18:47:52 -07002686 mHeavyWeightProcess.activities);
2687 for (int i=0; i<activities.size(); i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002688 ActivityRecord r = activities.get(i);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002689 if (!r.finishing) {
Dianne Hackbornbe707852011-11-11 14:32:10 -08002690 int index = mMainStack.indexOfTokenLocked(r.appToken);
Dianne Hackborn860755f2010-06-03 18:47:52 -07002691 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002692 mMainStack.finishActivityLocked(r, index, Activity.RESULT_CANCELED,
Dianne Hackborn860755f2010-06-03 18:47:52 -07002693 null, "finish-heavy");
2694 }
2695 }
2696 }
2697
Dianne Hackborn41203752012-08-31 14:05:51 -07002698 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
2699 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -07002700 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07002701 }
2702 }
2703
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002704 public void crashApplication(int uid, int initialPid, String packageName,
2705 String message) {
2706 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
2707 != PackageManager.PERMISSION_GRANTED) {
2708 String msg = "Permission Denial: crashApplication() from pid="
2709 + Binder.getCallingPid()
2710 + ", uid=" + Binder.getCallingUid()
2711 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
2712 Slog.w(TAG, msg);
2713 throw new SecurityException(msg);
2714 }
2715
2716 synchronized(this) {
2717 ProcessRecord proc = null;
2718
2719 // Figure out which process to kill. We don't trust that initialPid
2720 // still has any relation to current pids, so must scan through the
2721 // list.
2722 synchronized (mPidsSelfLocked) {
2723 for (int i=0; i<mPidsSelfLocked.size(); i++) {
2724 ProcessRecord p = mPidsSelfLocked.valueAt(i);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08002725 if (p.uid != uid) {
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002726 continue;
2727 }
2728 if (p.pid == initialPid) {
2729 proc = p;
2730 break;
2731 }
2732 for (String str : p.pkgList) {
2733 if (str.equals(packageName)) {
2734 proc = p;
2735 }
2736 }
2737 }
2738 }
2739
2740 if (proc == null) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07002741 Slog.w(TAG, "crashApplication: nothing for uid=" + uid
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002742 + " initialPid=" + initialPid
2743 + " packageName=" + packageName);
2744 return;
2745 }
2746
2747 if (proc.thread != null) {
Dianne Hackborn9f531192010-08-04 17:48:03 -07002748 if (proc.pid == Process.myPid()) {
2749 Log.w(TAG, "crashApplication: trying to crash self!");
2750 return;
2751 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07002752 long ident = Binder.clearCallingIdentity();
2753 try {
2754 proc.thread.scheduleCrash(message);
2755 } catch (RemoteException e) {
2756 }
2757 Binder.restoreCallingIdentity(ident);
2758 }
2759 }
2760 }
2761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002762 public final void finishSubActivity(IBinder token, String resultWho,
2763 int requestCode) {
2764 synchronized(this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002765 final long origId = Binder.clearCallingIdentity();
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002766 mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 Binder.restoreCallingIdentity(origId);
2768 }
2769 }
2770
Dianne Hackbornecc5a9c2012-04-26 18:56:09 -07002771 public boolean finishActivityAffinity(IBinder token) {
2772 synchronized(this) {
2773 final long origId = Binder.clearCallingIdentity();
2774 boolean res = mMainStack.finishActivityAffinityLocked(token);
2775 Binder.restoreCallingIdentity(origId);
2776 return res;
2777 }
2778 }
2779
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002780 public boolean willActivityBeVisible(IBinder token) {
2781 synchronized(this) {
2782 int i;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002783 for (i=mMainStack.mHistory.size()-1; i>=0; i--) {
2784 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08002785 if (r.appToken == token) {
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002786 return true;
2787 }
2788 if (r.fullscreen && !r.finishing) {
2789 return false;
2790 }
2791 }
2792 return true;
2793 }
2794 }
2795
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002796 public void overridePendingTransition(IBinder token, String packageName,
2797 int enterAnim, int exitAnim) {
2798 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002799 ActivityRecord self = mMainStack.isInStackLocked(token);
2800 if (self == null) {
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002801 return;
2802 }
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002803
2804 final long origId = Binder.clearCallingIdentity();
2805
2806 if (self.state == ActivityState.RESUMED
2807 || self.state == ActivityState.PAUSING) {
2808 mWindowManager.overridePendingAppTransition(packageName,
Dianne Hackborn84375872012-06-01 19:03:50 -07002809 enterAnim, exitAnim, null);
Dianne Hackborn3b3e1452009-09-24 19:22:12 -07002810 }
2811
2812 Binder.restoreCallingIdentity(origId);
2813 }
2814 }
2815
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002816 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002817 * Main function for removing an existing process from the activity manager
2818 * as a result of that process going away. Clears out all connections
2819 * to the process.
2820 */
2821 private final void handleAppDiedLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002822 boolean restarting, boolean allowRestart) {
2823 cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002824 if (!restarting) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002825 mLruProcesses.remove(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 }
2827
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002828 if (mProfileProc == app) {
2829 clearProfilerLocked();
2830 }
2831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002832 // Just in case...
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08002833 if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
2834 if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
2835 mMainStack.mPausingActivity = null;
2836 }
2837 if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
2838 mMainStack.mLastPausedActivity = null;
2839 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840
2841 // Remove this application's activities from active lists.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002842 mMainStack.removeHistoryRecordsForAppLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002843
2844 boolean atTop = true;
2845 boolean hasVisibleActivities = false;
2846
2847 // Clean out the history list.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002848 int i = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08002849 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002850 TAG, "Removing app " + app + " from history with " + i + " entries");
2851 while (i > 0) {
2852 i--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002853 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002854 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002855 TAG, "Record #" + i + " " + r + ": app=" + r.app);
2856 if (r.app == app) {
2857 if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002858 if (ActivityStack.DEBUG_ADD_REMOVE) {
2859 RuntimeException here = new RuntimeException("here");
2860 here.fillInStackTrace();
2861 Slog.i(TAG, "Removing activity " + r + " from stack at " + i
2862 + ": haveState=" + r.haveState
2863 + " stateNotNeeded=" + r.stateNotNeeded
2864 + " finishing=" + r.finishing
2865 + " state=" + r.state, here);
2866 }
2867 if (!r.finishing) {
2868 Slog.w(TAG, "Force removing " + r + ": app died, no saved state");
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -08002869 EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
2870 System.identityHashCode(r),
2871 r.task.taskId, r.shortComponentName,
2872 "proc died without state saved");
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002873 }
Dianne Hackborn5c607432012-02-28 14:44:19 -08002874 mMainStack.removeActivityFromHistoryLocked(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875
2876 } else {
2877 // We have the current state for this activity, so
2878 // it can be restarted later when needed.
Joe Onorato8a9b2202010-02-26 18:56:32 -08002879 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002880 TAG, "Keeping entry, setting app to null");
2881 if (r.visible) {
2882 hasVisibleActivities = true;
2883 }
2884 r.app = null;
2885 r.nowVisible = false;
2886 if (!r.haveState) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07002887 if (ActivityStack.DEBUG_SAVED_STATE) Slog.i(TAG,
2888 "App died, clearing saved state of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 r.icicle = null;
2890 }
2891 }
2892
Dianne Hackbornce86ba82011-07-13 19:33:41 -07002893 r.stack.cleanUpActivityLocked(r, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002894 }
2895 atTop = false;
2896 }
2897
2898 app.activities.clear();
2899
2900 if (app.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08002901 Slog.w(TAG, "Crash of app " + app.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002902 + " running instrumentation " + app.instrumentationClass);
2903 Bundle info = new Bundle();
2904 info.putString("shortMsg", "Process crashed.");
2905 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
2906 }
2907
2908 if (!restarting) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002909 if (!mMainStack.resumeTopActivityLocked(null)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 // If there was nothing to resume, and we are not already
2911 // restarting this process, but there is a visible activity that
2912 // is hosted by the process... then make sure all visible
2913 // activities are running, taking care of restarting this
2914 // process.
2915 if (hasVisibleActivities) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002916 mMainStack.ensureActivitiesVisibleLocked(null, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002917 }
2918 }
2919 }
2920 }
2921
2922 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
2923 IBinder threadBinder = thread.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 // Find the application record.
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002925 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2926 ProcessRecord rec = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
2928 return i;
2929 }
2930 }
2931 return -1;
2932 }
2933
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002934 final ProcessRecord getRecordForAppLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002935 IApplicationThread thread) {
2936 if (thread == null) {
2937 return null;
2938 }
2939
2940 int appIndex = getLRURecordIndexForAppLocked(thread);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002941 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002942 }
2943
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07002944 final void appDiedLocked(ProcessRecord app, int pid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002945 IApplicationThread thread) {
2946
2947 mProcDeaths[0]++;
2948
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002949 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
2950 synchronized (stats) {
2951 stats.noteProcessDiedLocked(app.info.uid, pid);
2952 }
2953
Magnus Edlund7bb25812010-02-24 15:45:06 +01002954 // Clean up already done if the process has been re-started.
2955 if (app.pid == pid && app.thread != null &&
2956 app.thread.asBinder() == thread.asBinder()) {
Dianne Hackborn906497c2010-05-10 15:57:38 -07002957 if (!app.killedBackground) {
2958 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
2959 + ") has died.");
2960 }
Doug Zongker2bec3d42009-12-04 12:52:44 -08002961 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Joe Onorato8a9b2202010-02-26 18:56:32 -08002962 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002963 TAG, "Dying app: " + app + ", pid: " + pid
2964 + ", thread: " + thread.asBinder());
2965 boolean doLowMem = app.instrumentationClass == null;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07002966 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002967
2968 if (doLowMem) {
2969 // If there are no longer any background processes running,
2970 // and the app that died was not running instrumentation,
2971 // then tell everyone we are now low on memory.
2972 boolean haveBg = false;
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002973 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2974 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn7d608422011-08-07 16:24:18 -07002975 if (rec.thread != null && rec.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002976 haveBg = true;
2977 break;
2978 }
2979 }
2980
2981 if (!haveBg) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002982 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002983 long now = SystemClock.uptimeMillis();
Dianne Hackborndd71fc82009-12-16 19:24:32 -08002984 for (int i=mLruProcesses.size()-1; i>=0; i--) {
2985 ProcessRecord rec = mLruProcesses.get(i);
Dianne Hackborn36124872009-10-08 16:22:03 -07002986 if (rec != app && rec.thread != null &&
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002987 (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
2988 // The low memory report is overriding any current
2989 // state for a GC request. Make sure to do
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002990 // heavy/important/visible/foreground processes first.
Dianne Hackborn7d608422011-08-07 16:24:18 -07002991 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002992 rec.lastRequestedGc = 0;
2993 } else {
2994 rec.lastRequestedGc = rec.lastLowMemory;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002995 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -07002996 rec.reportLowMemory = true;
2997 rec.lastLowMemory = now;
2998 mProcessesToGc.remove(rec);
2999 addProcessToGcListLocked(rec);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003000 }
3001 }
Dianne Hackborn04d6db32011-11-04 20:07:24 -07003002 mHandler.sendEmptyMessage(REPORT_MEM_USAGE);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07003003 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003004 }
3005 }
Magnus Edlund7bb25812010-02-24 15:45:06 +01003006 } else if (app.pid != pid) {
3007 // A new process has already been started.
Joe Onorato8a9b2202010-02-26 18:56:32 -08003008 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
Magnus Edlund7bb25812010-02-24 15:45:06 +01003009 + ") has died and restarted (pid " + app.pid + ").");
Dianne Hackborn28a8c2b2010-03-01 11:30:02 -08003010 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.pid, app.processName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003011 } else if (DEBUG_PROCESSES) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003012 Slog.d(TAG, "Received spurious death notification for thread "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003013 + thread.asBinder());
3014 }
3015 }
3016
Dan Egnor42471dd2010-01-07 17:25:22 -08003017 /**
3018 * If a stack trace dump file is configured, dump process stack traces.
Christopher Tate6ee412d2010-05-28 12:01:56 -07003019 * @param clearTraces causes the dump file to be erased prior to the new
3020 * traces being written, if true; when false, the new traces will be
3021 * appended to any existing file content.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003022 * @param firstPids of dalvik VM processes to dump stack traces for first
3023 * @param lastPids of dalvik VM processes to dump stack traces for last
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003024 * @param nativeProcs optional list of native process names to dump stack crawls
Dan Egnor42471dd2010-01-07 17:25:22 -08003025 * @return file containing stack traces, or null if no dump file is configured
3026 */
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003027 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003028 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003029 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3030 if (tracesPath == null || tracesPath.length() == 0) {
3031 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003033
3034 File tracesFile = new File(tracesPath);
3035 try {
3036 File tracesDir = tracesFile.getParentFile();
rpcraigec7ed14c2012-07-25 13:10:37 -04003037 if (!tracesDir.exists()) {
3038 tracesFile.mkdirs();
3039 if (!SELinux.restorecon(tracesDir)) {
3040 return null;
3041 }
3042 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003043 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3044
Christopher Tate6ee412d2010-05-28 12:01:56 -07003045 if (clearTraces && tracesFile.exists()) tracesFile.delete();
Dan Egnor42471dd2010-01-07 17:25:22 -08003046 tracesFile.createNewFile();
3047 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3048 } catch (IOException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003049 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
Dan Egnor42471dd2010-01-07 17:25:22 -08003050 return null;
3051 }
3052
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003053 dumpStackTraces(tracesPath, firstPids, processStats, lastPids, nativeProcs);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003054 return tracesFile;
3055 }
3056
3057 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003058 ProcessStats processStats, SparseArray<Boolean> lastPids, String[] nativeProcs) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003059 // Use a FileObserver to detect when traces finish writing.
3060 // The order of traces is considered important to maintain for legibility.
3061 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
3062 public synchronized void onEvent(int event, String path) { notify(); }
3063 };
3064
3065 try {
3066 observer.startWatching();
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003067
3068 // First collect all of the stacks of the most important pids.
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003069 if (firstPids != null) {
3070 try {
3071 int num = firstPids.size();
3072 for (int i = 0; i < num; i++) {
3073 synchronized (observer) {
3074 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
3075 observer.wait(200); // Wait for write-close, give up after 200msec
3076 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003077 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003078 } catch (InterruptedException e) {
3079 Log.wtf(TAG, e);
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003080 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003081 }
3082
3083 // Next measure CPU usage.
3084 if (processStats != null) {
3085 processStats.init();
3086 System.gc();
3087 processStats.update();
3088 try {
3089 synchronized (processStats) {
3090 processStats.wait(500); // measure over 1/2 second.
3091 }
3092 } catch (InterruptedException e) {
3093 }
3094 processStats.update();
3095
3096 // We'll take the stack crawls of just the top apps using CPU.
3097 final int N = processStats.countWorkingStats();
3098 int numProcs = 0;
3099 for (int i=0; i<N && numProcs<5; i++) {
3100 ProcessStats.Stats stats = processStats.getWorkingStats(i);
3101 if (lastPids.indexOfKey(stats.pid) >= 0) {
3102 numProcs++;
3103 try {
3104 synchronized (observer) {
3105 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
3106 observer.wait(200); // Wait for write-close, give up after 200msec
3107 }
3108 } catch (InterruptedException e) {
3109 Log.wtf(TAG, e);
3110 }
3111
3112 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003113 }
3114 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003115
Dan Egnor42471dd2010-01-07 17:25:22 -08003116 } finally {
3117 observer.stopWatching();
3118 }
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003119
3120 if (nativeProcs != null) {
3121 int[] pids = Process.getPidsForCommands(nativeProcs);
3122 if (pids != null) {
3123 for (int pid : pids) {
3124 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
3125 }
3126 }
3127 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003128 }
3129
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003130 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
Dianne Hackborn69dc66e2012-03-26 10:50:54 -07003131 if (true || IS_USER_BUILD) {
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003132 return;
3133 }
3134 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
3135 if (tracesPath == null || tracesPath.length() == 0) {
3136 return;
3137 }
3138
3139 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
3140 StrictMode.allowThreadDiskWrites();
3141 try {
3142 final File tracesFile = new File(tracesPath);
3143 final File tracesDir = tracesFile.getParentFile();
3144 final File tracesTmp = new File(tracesDir, "__tmp__");
3145 try {
rpcraigec7ed14c2012-07-25 13:10:37 -04003146 if (!tracesDir.exists()) {
3147 tracesFile.mkdirs();
3148 if (!SELinux.restorecon(tracesDir.getPath())) {
3149 return;
3150 }
3151 }
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003152 FileUtils.setPermissions(tracesDir.getPath(), 0775, -1, -1); // drwxrwxr-x
3153
3154 if (tracesFile.exists()) {
3155 tracesTmp.delete();
3156 tracesFile.renameTo(tracesTmp);
3157 }
3158 StringBuilder sb = new StringBuilder();
3159 Time tobj = new Time();
3160 tobj.set(System.currentTimeMillis());
3161 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
3162 sb.append(": ");
3163 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
3164 sb.append(" since ");
3165 sb.append(msg);
3166 FileOutputStream fos = new FileOutputStream(tracesFile);
3167 fos.write(sb.toString().getBytes());
3168 if (app == null) {
3169 fos.write("\n*** No application process!".getBytes());
3170 }
3171 fos.close();
3172 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
3173 } catch (IOException e) {
3174 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
3175 return;
3176 }
3177
3178 if (app != null) {
3179 ArrayList<Integer> firstPids = new ArrayList<Integer>();
3180 firstPids.add(app.pid);
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003181 dumpStackTraces(tracesPath, firstPids, null, null, null);
Dianne Hackborn2a29b3a2012-03-15 15:48:38 -07003182 }
3183
3184 File lastTracesFile = null;
3185 File curTracesFile = null;
3186 for (int i=9; i>=0; i--) {
3187 String name = String.format("slow%02d.txt", i);
3188 curTracesFile = new File(tracesDir, name);
3189 if (curTracesFile.exists()) {
3190 if (lastTracesFile != null) {
3191 curTracesFile.renameTo(lastTracesFile);
3192 } else {
3193 curTracesFile.delete();
3194 }
3195 }
3196 lastTracesFile = curTracesFile;
3197 }
3198 tracesFile.renameTo(curTracesFile);
3199 if (tracesTmp.exists()) {
3200 tracesTmp.renameTo(tracesFile);
3201 }
3202 } finally {
3203 StrictMode.setThreadPolicy(oldPolicy);
3204 }
3205 }
3206
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003207 final void appNotResponding(ProcessRecord app, ActivityRecord activity,
3208 ActivityRecord parent, final String annotation) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003209 ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
3210 SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
3211
Dianne Hackborn287952c2010-09-22 22:34:31 -07003212 if (mController != null) {
3213 try {
3214 // 0 == continue, -1 = kill process immediately
3215 int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
3216 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3217 } catch (RemoteException e) {
3218 mController = null;
3219 }
3220 }
3221
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003222 long anrTime = SystemClock.uptimeMillis();
3223 if (MONITOR_CPU_USAGE) {
3224 updateCpuStatsNow();
3225 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003226
3227 synchronized (this) {
3228 // PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
3229 if (mShuttingDown) {
3230 Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
3231 return;
3232 } else if (app.notResponding) {
3233 Slog.i(TAG, "Skipping duplicate ANR: " + app + " " + annotation);
3234 return;
3235 } else if (app.crashing) {
3236 Slog.i(TAG, "Crashing app skipping ANR: " + app + " " + annotation);
3237 return;
3238 }
3239
3240 // In case we come through here for the same app before completing
3241 // this one, mark as anring now so we will bail out.
3242 app.notResponding = true;
Dan Egnor42471dd2010-01-07 17:25:22 -08003243
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003244 // Log the ANR to the event log.
3245 EventLog.writeEvent(EventLogTags.AM_ANR, app.pid, app.processName, app.info.flags,
3246 annotation);
Dan Egnor42471dd2010-01-07 17:25:22 -08003247
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003248 // Dump thread traces as quickly as we can, starting with "interesting" processes.
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003249 firstPids.add(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003250
3251 int parentPid = app.pid;
3252 if (parent != null && parent.app != null && parent.app.pid > 0) parentPid = parent.app.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003253 if (parentPid != app.pid) firstPids.add(parentPid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003254
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003255 if (MY_PID != app.pid && MY_PID != parentPid) firstPids.add(MY_PID);
Dan Egnor42471dd2010-01-07 17:25:22 -08003256
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003257 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
3258 ProcessRecord r = mLruProcesses.get(i);
3259 if (r != null && r.thread != null) {
3260 int pid = r.pid;
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003261 if (pid > 0 && pid != app.pid && pid != parentPid && pid != MY_PID) {
3262 if (r.persistent) {
3263 firstPids.add(pid);
3264 } else {
3265 lastPids.put(pid, Boolean.TRUE);
3266 }
3267 }
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003269 }
3270 }
3271
Dan Egnor42471dd2010-01-07 17:25:22 -08003272 // Log the ANR to the main log.
Jeff Browndeb6ed82012-04-10 14:26:26 -07003273 StringBuilder info = new StringBuilder();
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07003274 info.setLength(0);
Dan Egnor42471dd2010-01-07 17:25:22 -08003275 info.append("ANR in ").append(app.processName);
3276 if (activity != null && activity.shortComponentName != null) {
3277 info.append(" (").append(activity.shortComponentName).append(")");
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07003278 }
Eric Rowe6f4f6192010-02-17 18:29:04 -08003279 info.append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 if (annotation != null) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003281 info.append("Reason: ").append(annotation).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003282 }
Dan Egnor42471dd2010-01-07 17:25:22 -08003283 if (parent != null && parent != activity) {
Eric Rowe6f4f6192010-02-17 18:29:04 -08003284 info.append("Parent: ").append(parent.shortComponentName).append("\n");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003285 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003286
Dianne Hackborn287952c2010-09-22 22:34:31 -07003287 final ProcessStats processStats = new ProcessStats(true);
3288
Dianne Hackbornf72467a2012-06-08 17:23:59 -07003289 File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003290
Dan Egnor42471dd2010-01-07 17:25:22 -08003291 String cpuInfo = null;
3292 if (MONITOR_CPU_USAGE) {
3293 updateCpuStatsNow();
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003294 synchronized (mProcessStatsThread) {
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003295 cpuInfo = mProcessStats.printCurrentState(anrTime);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003296 }
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003297 info.append(processStats.printCurrentLoad());
Dan Egnor42471dd2010-01-07 17:25:22 -08003298 info.append(cpuInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003299 }
3300
Dianne Hackborn6b1afeb2010-08-31 15:40:21 -07003301 info.append(processStats.printCurrentState(anrTime));
3302
Joe Onorato8a9b2202010-02-26 18:56:32 -08003303 Slog.e(TAG, info.toString());
Dan Egnor42471dd2010-01-07 17:25:22 -08003304 if (tracesFile == null) {
3305 // There is no trace file, so dump (only) the alleged culprit's threads to the log
3306 Process.sendSignal(app.pid, Process.SIGNAL_QUIT);
3307 }
3308
Jeff Sharkeya353d262011-10-28 11:12:06 -07003309 addErrorToDropBox("anr", app, app.processName, activity, parent, annotation,
3310 cpuInfo, tracesFile, null);
Dan Egnor42471dd2010-01-07 17:25:22 -08003311
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003312 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003313 try {
Dan Egnor42471dd2010-01-07 17:25:22 -08003314 // 0 == show dialog, 1 = keep waiting, -1 = kill process immediately
3315 int res = mController.appNotResponding(app.processName, app.pid, info.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 if (res != 0) {
Dan Egnor42471dd2010-01-07 17:25:22 -08003317 if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
3318 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 }
3320 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07003321 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003322 }
3323 }
3324
Dan Egnor42471dd2010-01-07 17:25:22 -08003325 // Unless configured otherwise, swallow ANRs in background processes & kill the process.
3326 boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
3327 Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003328
3329 synchronized (this) {
3330 if (!showBackground && !app.isInterestingToUserLocked() && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003331 Slog.w(TAG, "Killing " + app + ": background ANR");
3332 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
3333 app.processName, app.setAdj, "background ANR");
3334 Process.killProcessQuiet(app.pid);
Dianne Hackbornad5499d2010-03-29 18:08:45 -07003335 return;
3336 }
3337
3338 // Set the app's notResponding state, and look up the errorReportReceiver
3339 makeAppNotRespondingLocked(app,
3340 activity != null ? activity.shortComponentName : null,
3341 annotation != null ? "ANR " + annotation : "ANR",
3342 info.toString());
3343
3344 // Bring up the infamous App Not Responding dialog
3345 Message msg = Message.obtain();
3346 HashMap map = new HashMap();
3347 msg.what = SHOW_NOT_RESPONDING_MSG;
3348 msg.obj = map;
3349 map.put("app", app);
3350 if (activity != null) {
3351 map.put("activity", activity);
3352 }
3353
3354 mHandler.sendMessage(msg);
Dan Egnor42471dd2010-01-07 17:25:22 -08003355 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003356 }
3357
Dianne Hackborn0dad3642010-09-09 21:25:35 -07003358 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
3359 if (!mLaunchWarningShown) {
3360 mLaunchWarningShown = true;
3361 mHandler.post(new Runnable() {
3362 @Override
3363 public void run() {
3364 synchronized (ActivityManagerService.this) {
3365 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
3366 d.show();
3367 mHandler.postDelayed(new Runnable() {
3368 @Override
3369 public void run() {
3370 synchronized (ActivityManagerService.this) {
3371 d.dismiss();
3372 mLaunchWarningShown = false;
3373 }
3374 }
3375 }, 4000);
3376 }
3377 }
3378 });
3379 }
3380 }
3381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003382 public boolean clearApplicationUserData(final String packageName,
Amith Yamasani742a6712011-05-04 14:49:28 -07003383 final IPackageDataObserver observer, final int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003384 enforceNotIsolatedCaller("clearApplicationUserData");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003385 int uid = Binder.getCallingUid();
3386 int pid = Binder.getCallingPid();
3387 long callingId = Binder.clearCallingIdentity();
3388 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003389 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 int pkgUid = -1;
3391 synchronized(this) {
3392 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003393 pkgUid = pm.getPackageUid(packageName, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 } catch (RemoteException e) {
3395 }
3396 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003397 Slog.w(TAG, "Invalid packageName:" + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003398 return false;
3399 }
3400 if (uid == pkgUid || checkComponentPermission(
3401 android.Manifest.permission.CLEAR_APP_USER_DATA,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08003402 pid, uid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003404 forceStopPackageLocked(packageName, pkgUid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 } else {
3406 throw new SecurityException(pid+" does not have permission:"+
3407 android.Manifest.permission.CLEAR_APP_USER_DATA+" to clear data" +
3408 "for process:"+packageName);
3409 }
3410 }
3411
3412 try {
3413 //clear application user data
Amith Yamasani483f3b02012-03-13 16:08:00 -07003414 pm.clearApplicationUserData(packageName, observer, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
3416 Uri.fromParts("package", packageName, null));
3417 intent.putExtra(Intent.EXTRA_UID, pkgUid);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003418 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
Amith Yamasani742a6712011-05-04 14:49:28 -07003419 null, null, 0, null, null, null, false, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003420 } catch (RemoteException e) {
3421 }
3422 } finally {
3423 Binder.restoreCallingIdentity(callingId);
3424 }
3425 return true;
3426 }
3427
Dianne Hackborn03abb812010-01-04 18:43:19 -08003428 public void killBackgroundProcesses(final String packageName) {
3429 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3430 != PackageManager.PERMISSION_GRANTED &&
3431 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
3432 != PackageManager.PERMISSION_GRANTED) {
3433 String msg = "Permission Denial: killBackgroundProcesses() from pid="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003434 + Binder.getCallingPid()
3435 + ", uid=" + Binder.getCallingUid()
Dianne Hackborn03abb812010-01-04 18:43:19 -08003436 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003437 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003438 throw new SecurityException(msg);
3439 }
3440
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07003441 int userId = UserHandle.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003442 long callingId = Binder.clearCallingIdentity();
3443 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003444 IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445 int pkgUid = -1;
3446 synchronized(this) {
3447 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003448 pkgUid = pm.getPackageUid(packageName, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003449 } catch (RemoteException e) {
3450 }
3451 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003452 Slog.w(TAG, "Invalid packageName: " + packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003453 return;
3454 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003455 killPackageProcessesLocked(packageName, pkgUid, -1,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003456 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
3457 }
3458 } finally {
3459 Binder.restoreCallingIdentity(callingId);
3460 }
3461 }
3462
3463 public void killAllBackgroundProcesses() {
3464 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
3465 != PackageManager.PERMISSION_GRANTED) {
3466 String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
3467 + Binder.getCallingPid()
3468 + ", uid=" + Binder.getCallingUid()
3469 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
3470 Slog.w(TAG, msg);
3471 throw new SecurityException(msg);
3472 }
3473
3474 long callingId = Binder.clearCallingIdentity();
3475 try {
3476 synchronized(this) {
3477 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
3478 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3479 final int NA = apps.size();
3480 for (int ia=0; ia<NA; ia++) {
3481 ProcessRecord app = apps.valueAt(ia);
3482 if (app.persistent) {
3483 // we don't kill persistent processes
3484 continue;
3485 }
3486 if (app.removed) {
3487 procs.add(app);
3488 } else if (app.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
3489 app.removed = true;
3490 procs.add(app);
3491 }
3492 }
3493 }
3494
3495 int N = procs.size();
3496 for (int i=0; i<N; i++) {
3497 removeProcessLocked(procs.get(i), false, true, "kill all background");
3498 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003499 }
3500 } finally {
3501 Binder.restoreCallingIdentity(callingId);
3502 }
3503 }
3504
3505 public void forceStopPackage(final String packageName) {
3506 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
3507 != PackageManager.PERMISSION_GRANTED) {
3508 String msg = "Permission Denial: forceStopPackage() from pid="
3509 + Binder.getCallingPid()
3510 + ", uid=" + Binder.getCallingUid()
3511 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003512 Slog.w(TAG, msg);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003513 throw new SecurityException(msg);
3514 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07003515 final int userId = UserHandle.getCallingUserId();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003516 long callingId = Binder.clearCallingIdentity();
3517 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003518 IPackageManager pm = AppGlobals.getPackageManager();
Dianne Hackborn03abb812010-01-04 18:43:19 -08003519 int pkgUid = -1;
3520 synchronized(this) {
3521 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003522 pkgUid = pm.getPackageUid(packageName, userId);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003523 } catch (RemoteException e) {
3524 }
3525 if (pkgUid == -1) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003526 Slog.w(TAG, "Invalid packageName: " + packageName);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003527 return;
3528 }
3529 forceStopPackageLocked(packageName, pkgUid);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003530 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003531 pm.setPackageStoppedState(packageName, true, userId);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003532 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08003533 } catch (IllegalArgumentException e) {
3534 Slog.w(TAG, "Failed trying to unstop package "
3535 + packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08003536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003537 }
3538 } finally {
3539 Binder.restoreCallingIdentity(callingId);
3540 }
3541 }
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003542
3543 /*
3544 * The pkg name and uid have to be specified.
3545 * @see android.app.IActivityManager#killApplicationWithUid(java.lang.String, int)
3546 */
3547 public void killApplicationWithUid(String pkg, int uid) {
3548 if (pkg == null) {
3549 return;
3550 }
3551 // Make sure the uid is valid.
3552 if (uid < 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003553 Slog.w(TAG, "Invalid uid specified for pkg : " + pkg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003554 return;
3555 }
3556 int callerUid = Binder.getCallingUid();
3557 // Only the system server can kill an application
3558 if (callerUid == Process.SYSTEM_UID) {
Suchi Amalapurapud9d25762009-08-17 16:57:03 -07003559 // Post an aysnc message to kill the application
3560 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
3561 msg.arg1 = uid;
3562 msg.arg2 = 0;
3563 msg.obj = pkg;
Suchi Amalapurapud50066f2009-08-18 16:57:41 -07003564 mHandler.sendMessage(msg);
Suchi Amalapurapu261e66a2009-07-27 15:21:34 -07003565 } else {
3566 throw new SecurityException(callerUid + " cannot kill pkg: " +
3567 pkg);
3568 }
3569 }
3570
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003571 public void closeSystemDialogs(String reason) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003572 enforceNotIsolatedCaller("closeSystemDialogs");
Dianne Hackborne302a162012-05-15 14:58:32 -07003573
3574 final int uid = Binder.getCallingUid();
3575 final long origId = Binder.clearCallingIdentity();
3576 synchronized (this) {
3577 closeSystemDialogsLocked(uid, reason);
3578 }
3579 Binder.restoreCallingIdentity(origId);
3580 }
3581
3582 void closeSystemDialogsLocked(int callingUid, String reason) {
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003583 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003584 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003585 if (reason != null) {
3586 intent.putExtra("reason", reason);
3587 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003588 mWindowManager.closeSystemDialogs(reason);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07003589
Dianne Hackborne302a162012-05-15 14:58:32 -07003590 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
3591 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn1927ae82012-06-22 15:21:36 -07003592 if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
Dianne Hackborne302a162012-05-15 14:58:32 -07003593 r.stack.finishActivityLocked(r, i,
3594 Activity.RESULT_CANCELED, null, "close-sys");
Dianne Hackbornffa42482009-09-23 22:20:11 -07003595 }
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003596 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07003597
3598 final long origId = Binder.clearCallingIdentity();
3599 try {
3600 broadcastIntentLocked(null, null, intent, null,
3601 null, 0, null, null, null, false, false, -1,
3602 callingUid, UserHandle.USER_ALL);
3603 } finally {
3604 Binder.restoreCallingIdentity(origId);
3605 }
Dianne Hackborna6ddc8a2009-07-28 17:49:55 -07003606 }
Dianne Hackborne302a162012-05-15 14:58:32 -07003607
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003608 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids)
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003609 throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003610 enforceNotIsolatedCaller("getProcessMemoryInfo");
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003611 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
3612 for (int i=pids.length-1; i>=0; i--) {
3613 infos[i] = new Debug.MemoryInfo();
3614 Debug.getMemoryInfo(pids[i], infos[i]);
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003615 }
Dianne Hackborn4f21c4c2009-09-17 10:24:05 -07003616 return infos;
Dianne Hackborn3025ef32009-08-31 21:31:47 -07003617 }
Christopher Tate5e1ab332009-09-01 20:32:49 -07003618
Dianne Hackbornb437e092011-08-05 17:50:29 -07003619 public long[] getProcessPss(int[] pids) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08003620 enforceNotIsolatedCaller("getProcessPss");
Dianne Hackbornb437e092011-08-05 17:50:29 -07003621 long[] pss = new long[pids.length];
3622 for (int i=pids.length-1; i>=0; i--) {
3623 pss[i] = Debug.getPss(pids[i]);
3624 }
3625 return pss;
3626 }
3627
Christopher Tate5e1ab332009-09-01 20:32:49 -07003628 public void killApplicationProcess(String processName, int uid) {
3629 if (processName == null) {
3630 return;
3631 }
3632
3633 int callerUid = Binder.getCallingUid();
3634 // Only the system server can kill an application
3635 if (callerUid == Process.SYSTEM_UID) {
3636 synchronized (this) {
3637 ProcessRecord app = getProcessRecordLocked(processName, uid);
Christopher Tate4a627c72011-04-01 14:43:32 -07003638 if (app != null && app.thread != null) {
Christopher Tate5e1ab332009-09-01 20:32:49 -07003639 try {
3640 app.thread.scheduleSuicide();
3641 } catch (RemoteException e) {
3642 // If the other end already died, then our work here is done.
3643 }
3644 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003645 Slog.w(TAG, "Process/uid not found attempting kill of "
Christopher Tate5e1ab332009-09-01 20:32:49 -07003646 + processName + " / " + uid);
3647 }
3648 }
3649 } else {
3650 throw new SecurityException(callerUid + " cannot kill app process: " +
3651 processName);
3652 }
3653 }
3654
Dianne Hackborn03abb812010-01-04 18:43:19 -08003655 private void forceStopPackageLocked(final String packageName, int uid) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003656 forceStopPackageLocked(packageName, uid, false, false, true, false,
3657 UserHandle.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003658 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
3659 Uri.fromParts("package", packageName, null));
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07003660 if (!mProcessesReady) {
3661 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003663 intent.putExtra(Intent.EXTRA_UID, uid);
3664 broadcastIntentLocked(null, null, intent,
3665 null, null, 0, null, null, null,
Amith Yamasani742a6712011-05-04 14:49:28 -07003666 false, false,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07003667 MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003668 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003669
3670 private void forceStopUserLocked(int userId) {
3671 forceStopPackageLocked(null, -1, false, false, true, false, userId);
3672 Intent intent = new Intent(Intent.ACTION_USER_STOPPED);
3673 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
3674 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
3675 broadcastIntentLocked(null, null, intent,
3676 null, null, 0, null, null, null,
3677 false, false,
3678 MY_PID, Process.SYSTEM_UID, userId);
3679 }
3680
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003681 private final boolean killPackageProcessesLocked(String packageName, int uid,
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003682 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
3683 boolean doit, boolean evenPersistent, String reason) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003684 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003685
Dianne Hackborn03abb812010-01-04 18:43:19 -08003686 // Remove all processes this package may have touched: all with the
3687 // same UID (except for the system or root user), and all whose name
3688 // matches the package name.
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003689 final String procNamePrefix = packageName != null ? (packageName + ":") : null;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003690 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
3691 final int NA = apps.size();
3692 for (int ia=0; ia<NA; ia++) {
3693 ProcessRecord app = apps.valueAt(ia);
Christopher Tate3dacd842011-08-19 14:56:15 -07003694 if (app.persistent && !evenPersistent) {
Christopher Tate064d8422011-07-26 15:38:07 -07003695 // we don't kill persistent processes
3696 continue;
3697 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003698 if (app.removed) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003699 if (doit) {
3700 procs.add(app);
3701 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003702 // If no package is specified, we call all processes under the
3703 // give user id.
3704 } else if (packageName == null) {
3705 if (app.userId == userId) {
3706 if (app.setAdj >= minOomAdj) {
3707 if (!doit) {
3708 return true;
3709 }
3710 app.removed = true;
3711 procs.add(app);
3712 }
3713 }
Amith Yamasani13593602012-03-22 16:16:17 -07003714 // If uid is specified and the uid and process name match
3715 // Or, the uid is not specified and the process name matches
3716 } else if (((uid > 0 && uid != Process.SYSTEM_UID && app.info.uid == uid)
Amith Yamasani34db3d62012-04-02 16:35:19 -07003717 || ((app.processName.equals(packageName)
3718 || app.processName.startsWith(procNamePrefix))
3719 && uid < 0))) {
Dianne Hackborn03abb812010-01-04 18:43:19 -08003720 if (app.setAdj >= minOomAdj) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003721 if (!doit) {
3722 return true;
3723 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003724 app.removed = true;
3725 procs.add(app);
3726 }
3727 }
3728 }
3729 }
3730
3731 int N = procs.size();
3732 for (int i=0; i<N; i++) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003733 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
Dianne Hackborn03abb812010-01-04 18:43:19 -08003734 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003735 return N > 0;
Dianne Hackborn03abb812010-01-04 18:43:19 -08003736 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003737
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003738 private final boolean forceStopPackageLocked(String name, int uid,
Christopher Tate3dacd842011-08-19 14:56:15 -07003739 boolean callerWillRestart, boolean purgeCache, boolean doit,
Amith Yamasani483f3b02012-03-13 16:08:00 -07003740 boolean evenPersistent, int userId) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07003741 int i;
3742 int N;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003743
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003744 if (uid < 0 && name != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003745 try {
Amith Yamasani483f3b02012-03-13 16:08:00 -07003746 uid = AppGlobals.getPackageManager().getPackageUid(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 } catch (RemoteException e) {
3748 }
3749 }
3750
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003751 if (doit) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003752 if (name != null) {
3753 Slog.i(TAG, "Force stopping package " + name + " uid=" + uid);
3754 } else {
3755 Slog.i(TAG, "Force stopping user " + userId);
3756 }
Dianne Hackborn03abb812010-01-04 18:43:19 -08003757
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003758 Iterator<SparseArray<Long>> badApps = mProcessCrashTimes.getMap().values().iterator();
3759 while (badApps.hasNext()) {
3760 SparseArray<Long> ba = badApps.next();
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003761 for (i=ba.size()-1; i>=0; i--) {
3762 boolean remove = false;
3763 final int entUid = ba.keyAt(i);
3764 if (name != null) {
3765 if (entUid == uid) {
3766 remove = true;
3767 }
3768 } else if (UserHandle.getUserId(entUid) == userId) {
3769 remove = true;
3770 }
3771 if (remove) {
3772 ba.removeAt(i);
3773 }
3774 }
3775 if (ba.size() == 0) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003776 badApps.remove();
3777 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003778 }
3779 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003780
3781 boolean didSomething = killPackageProcessesLocked(name, uid,
3782 name == null ? userId : -1 , -100, callerWillRestart, false,
3783 doit, evenPersistent,
3784 name == null ? ("force stop user " + userId) : ("force stop " + name));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003785
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003786 TaskRecord lastTask = null;
3787 for (i=0; i<mMainStack.mHistory.size(); i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07003788 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003789 final boolean samePackage = r.packageName.equals(name)
3790 || (name == null && r.userId == userId);
Amith Yamasani13593602012-03-22 16:16:17 -07003791 if (r.userId == userId
3792 && (samePackage || r.task == lastTask)
Christopher Tate3dacd842011-08-19 14:56:15 -07003793 && (r.app == null || evenPersistent || !r.app.persistent)) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003794 if (!doit) {
Dianne Hackborn80a7ac12011-09-22 18:32:52 -07003795 if (r.finishing) {
3796 // If this activity is just finishing, then it is not
3797 // interesting as far as something to stop.
3798 continue;
3799 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003800 return true;
3801 }
3802 didSomething = true;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003803 Slog.i(TAG, " Force finishing activity " + r);
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003804 if (samePackage) {
3805 if (r.app != null) {
3806 r.app.removed = true;
3807 }
3808 r.app = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003809 }
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003810 lastTask = r.task;
3811 if (r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED,
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07003812 null, "force-stop", true)) {
Dianne Hackborne5ba16a2011-09-09 12:35:29 -07003813 i--;
3814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003815 }
3816 }
3817
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003818 if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
3819 if (!doit) {
3820 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003822 didSomething = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003823 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003824
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07003825 if (name == null) {
3826 // Remove all sticky broadcasts from this user.
3827 mStickyBroadcasts.remove(userId);
3828 }
3829
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003830 ArrayList<ContentProviderRecord> providers = new ArrayList<ContentProviderRecord>();
Amith Yamasani13593602012-03-22 16:16:17 -07003831 for (ContentProviderRecord provider : mProviderMap.getProvidersByClass(userId).values()) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003832 if ((name == null || provider.info.packageName.equals(name))
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003833 && (provider.proc == null || evenPersistent || !provider.proc.persistent)) {
3834 if (!doit) {
3835 return true;
3836 }
3837 didSomething = true;
3838 providers.add(provider);
3839 }
3840 }
3841
3842 N = providers.size();
3843 for (i=0; i<N; i++) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003844 removeDyingProviderLocked(null, providers.get(i), true);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07003845 }
3846
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003847 if (doit) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -07003848 if (purgeCache && name != null) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003849 AttributeCache ac = AttributeCache.instance();
3850 if (ac != null) {
3851 ac.removePackage(name);
3852 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003853 }
Dianne Hackborn38cc8962011-10-13 11:33:55 -07003854 if (mBooted) {
3855 mMainStack.resumeTopActivityLocked(null);
3856 mMainStack.scheduleIdleLocked();
3857 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -08003858 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08003859
3860 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003861 }
3862
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003863 private final boolean removeProcessLocked(ProcessRecord app,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003864 boolean callerWillRestart, boolean allowRestart, String reason) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003865 final String name = app.processName;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003866 final int uid = app.uid;
Joe Onorato8a9b2202010-02-26 18:56:32 -08003867 if (DEBUG_PROCESSES) Slog.d(
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003868 TAG, "Force removing proc " + app.toShortString() + " (" + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003869 + "/" + uid + ")");
3870
3871 mProcessNames.remove(name, uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003872 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003873 if (mHeavyWeightProcess == app) {
Dianne Hackborn41203752012-08-31 14:05:51 -07003874 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3875 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -07003876 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003877 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003878 boolean needRestart = false;
3879 if (app.pid > 0 && app.pid != MY_PID) {
3880 int pid = app.pid;
3881 synchronized (mPidsSelfLocked) {
3882 mPidsSelfLocked.remove(pid);
3883 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3884 }
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003885 Slog.i(TAG, "Killing proc " + app.toShortString() + ": " + reason);
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003886 handleAppDiedLocked(app, true, allowRestart);
Dianne Hackborndd71fc82009-12-16 19:24:32 -08003887 mLruProcesses.remove(app);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08003888 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003889
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003890 if (app.persistent && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003891 if (!callerWillRestart) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003892 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003893 } else {
3894 needRestart = true;
3895 }
3896 }
3897 } else {
3898 mRemovedProcesses.add(app);
3899 }
3900
3901 return needRestart;
3902 }
3903
3904 private final void processStartTimedOutLocked(ProcessRecord app) {
3905 final int pid = app.pid;
3906 boolean gone = false;
3907 synchronized (mPidsSelfLocked) {
3908 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
3909 if (knownApp != null && knownApp.thread == null) {
3910 mPidsSelfLocked.remove(pid);
3911 gone = true;
3912 }
3913 }
3914
3915 if (gone) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003916 Slog.w(TAG, "Process " + app + " failed to attach");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003917 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, pid, app.uid,
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003918 app.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08003919 mProcessNames.remove(app.processName, app.uid);
3920 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -07003921 if (mHeavyWeightProcess == app) {
Dianne Hackborn41203752012-08-31 14:05:51 -07003922 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
3923 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -07003924 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -07003925 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003926 // Take care of any launching providers waiting for this process.
3927 checkAppInLaunchingProvidersLocked(app, true);
3928 // Take care of any services that are waiting for the process.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003929 mServices.processStartTimedOutLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003930 EventLog.writeEvent(EventLogTags.AM_KILL, pid,
3931 app.processName, app.setAdj, "start timeout");
3932 Process.killProcessQuiet(pid);
Christopher Tate181fafa2009-05-14 11:12:14 -07003933 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003934 Slog.w(TAG, "Unattached app died before backup, skipping");
Christopher Tate181fafa2009-05-14 11:12:14 -07003935 try {
3936 IBackupManager bm = IBackupManager.Stub.asInterface(
3937 ServiceManager.getService(Context.BACKUP_SERVICE));
3938 bm.agentDisconnected(app.info.packageName);
3939 } catch (RemoteException e) {
3940 // Can't happen; the backup manager is local
3941 }
3942 }
Christopher Tatef46723b2012-01-26 14:19:24 -08003943 if (isPendingBroadcastProcessLocked(pid)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003944 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
Christopher Tatef46723b2012-01-26 14:19:24 -08003945 skipPendingBroadcastLocked(pid);
Dianne Hackbornf670ef72009-11-16 13:59:16 -08003946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003947 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003948 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003949 }
3950 }
3951
3952 private final boolean attachApplicationLocked(IApplicationThread thread,
3953 int pid) {
3954
3955 // Find the application record that is being attached... either via
3956 // the pid if we are running in multiple processes, or just pull the
3957 // next app record if we are emulating process with anonymous threads.
3958 ProcessRecord app;
3959 if (pid != MY_PID && pid >= 0) {
3960 synchronized (mPidsSelfLocked) {
3961 app = mPidsSelfLocked.get(pid);
3962 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003963 } else {
3964 app = null;
3965 }
3966
3967 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08003968 Slog.w(TAG, "No pending application record for pid " + pid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 + " (IApplicationThread " + thread + "); dropping process");
Doug Zongker2bec3d42009-12-04 12:52:44 -08003970 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 if (pid > 0 && pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07003972 Process.killProcessQuiet(pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973 } else {
3974 try {
3975 thread.scheduleExit();
3976 } catch (Exception e) {
3977 // Ignore exceptions.
3978 }
3979 }
3980 return false;
3981 }
3982
3983 // If this application record is still attached to a previous
3984 // process, clean it up now.
3985 if (app.thread != null) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -07003986 handleAppDiedLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003987 }
3988
3989 // Tell the process all about itself.
3990
Joe Onorato8a9b2202010-02-26 18:56:32 -08003991 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003992 TAG, "Binding process pid " + pid + " to record " + app);
3993
3994 String processName = app.processName;
3995 try {
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07003996 AppDeathRecipient adr = new AppDeathRecipient(
3997 app, pid, thread);
3998 thread.asBinder().linkToDeath(adr, 0);
3999 app.deathRecipient = adr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 } catch (RemoteException e) {
4001 app.resetPackageList();
4002 startProcessLocked(app, "link fail", processName);
4003 return false;
4004 }
4005
Doug Zongker2bec3d42009-12-04 12:52:44 -08004006 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.pid, app.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004007
4008 app.thread = thread;
4009 app.curAdj = app.setAdj = -100;
Dianne Hackborn09c916b2009-12-08 14:50:51 -08004010 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
4011 app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004012 app.forcingToForeground = null;
4013 app.foregroundServices = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07004014 app.hasShownUi = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004015 app.debugging = false;
4016
4017 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
4018
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004019 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004020 List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004022 if (!normalMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004023 Slog.i(TAG, "Launching preboot mode app: " + app);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004024 }
4025
Joe Onorato8a9b2202010-02-26 18:56:32 -08004026 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 TAG, "New app record " + app
4028 + " thread=" + thread.asBinder() + " pid=" + pid);
4029 try {
4030 int testMode = IApplicationThread.DEBUG_OFF;
4031 if (mDebugApp != null && mDebugApp.equals(processName)) {
4032 testMode = mWaitForDebugger
4033 ? IApplicationThread.DEBUG_WAIT
4034 : IApplicationThread.DEBUG_ON;
4035 app.debugging = true;
4036 if (mDebugTransient) {
4037 mDebugApp = mOrigDebugApp;
4038 mWaitForDebugger = mOrigWaitForDebugger;
4039 }
4040 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004041 String profileFile = app.instrumentationProfileFile;
4042 ParcelFileDescriptor profileFd = null;
4043 boolean profileAutoStop = false;
4044 if (mProfileApp != null && mProfileApp.equals(processName)) {
4045 mProfileProc = app;
4046 profileFile = mProfileFile;
4047 profileFd = mProfileFd;
4048 profileAutoStop = mAutoStopProfiler;
4049 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08004050 boolean enableOpenGlTrace = false;
4051 if (mOpenGlTraceApp != null && mOpenGlTraceApp.equals(processName)) {
4052 enableOpenGlTrace = true;
4053 mOpenGlTraceApp = null;
4054 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004055
Christopher Tate181fafa2009-05-14 11:12:14 -07004056 // If the app is being launched for restore or full backup, set it up specially
4057 boolean isRestrictedBackupMode = false;
4058 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
4059 isRestrictedBackupMode = (mBackupTarget.backupMode == BackupRecord.RESTORE)
Christopher Tate75a99702011-05-18 16:28:19 -07004060 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
Christopher Tate181fafa2009-05-14 11:12:14 -07004061 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL);
4062 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004063
Dianne Hackbornd7f6daa2009-06-22 17:06:35 -07004064 ensurePackageDexOpt(app.instrumentationInfo != null
4065 ? app.instrumentationInfo.packageName
4066 : app.info.packageName);
4067 if (app.instrumentationClass != null) {
4068 ensurePackageDexOpt(app.instrumentationClass.getPackageName());
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004069 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08004070 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Binding proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07004071 + processName + " with config " + mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004072 ApplicationInfo appInfo = app.instrumentationInfo != null
4073 ? app.instrumentationInfo : app.info;
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -07004074 app.compat = compatibilityInfoForPackageLocked(appInfo);
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004075 if (profileFd != null) {
4076 profileFd = profileFd.dup();
4077 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004078 thread.bindApplication(processName, appInfo, providers,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004079 app.instrumentationClass, profileFile, profileFd, profileAutoStop,
Siva Velusamy92a8b222012-03-09 16:24:04 -08004080 app.instrumentationArguments, app.instrumentationWatcher, testMode,
4081 enableOpenGlTrace, isRestrictedBackupMode || !normalMode, app.persistent,
Dianne Hackborn813075a62011-11-14 17:45:19 -08004082 new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004083 mCoreSettingsObserver.getCoreSettingsLocked());
Dianne Hackborndd71fc82009-12-16 19:24:32 -08004084 updateLruProcessLocked(app, false, true);
Dianne Hackbornfd12af42009-08-27 00:44:33 -07004085 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004086 } catch (Exception e) {
4087 // todo: Yikes! What should we do? For now we will try to
4088 // start another process, but that could easily get us in
4089 // an infinite loop of restarting processes...
Joe Onorato8a9b2202010-02-26 18:56:32 -08004090 Slog.w(TAG, "Exception thrown during bind!", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091
4092 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -07004093 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094 startProcessLocked(app, "bind fail", processName);
4095 return false;
4096 }
4097
4098 // Remove this record from the list of starting applications.
4099 mPersistentStartingProcesses.remove(app);
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004100 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
4101 "Attach application locked removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004102 mProcessesOnHold.remove(app);
4103
4104 boolean badApp = false;
4105 boolean didSomething = false;
4106
4107 // See if the top visible activity is waiting to run in this process...
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004108 ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
Christopher Tate04c0af82010-06-07 18:35:20 -07004109 if (hr != null && normalMode) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004110 if (hr.app == null && app.uid == hr.info.applicationInfo.uid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004111 && processName.equals(hr.processName)) {
4112 try {
Mike Lockwood3a74bd32011-08-12 13:55:22 -07004113 if (mHeadless) {
4114 Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
4115 } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004116 didSomething = true;
4117 }
4118 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004119 Slog.w(TAG, "Exception in new application when starting activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004120 + hr.intent.getComponent().flattenToShortString(), e);
4121 badApp = true;
4122 }
4123 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004124 mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004125 }
4126 }
4127
4128 // Find any services that should be running in this process...
Dianne Hackborn599db5c2012-08-03 19:28:48 -07004129 if (!badApp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 try {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07004131 didSomething |= mServices.attachApplicationLocked(app, processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004132 } catch (Exception e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004133 badApp = true;
4134 }
4135 }
4136
Christopher Tatef46723b2012-01-26 14:19:24 -08004137 // Check if a next-broadcast receiver is in this process...
4138 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004139 try {
Christopher Tatef46723b2012-01-26 14:19:24 -08004140 didSomething = sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004141 } catch (Exception e) {
Christopher Tatef46723b2012-01-26 14:19:24 -08004142 // If the app died trying to launch the receiver we declare it 'bad'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004143 badApp = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004144 }
4145 }
4146
Christopher Tate181fafa2009-05-14 11:12:14 -07004147 // Check whether the next backup agent is in this process...
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004148 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004149 if (DEBUG_BACKUP) Slog.v(TAG, "New app is backup target, launching agent for " + app);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07004150 ensurePackageDexOpt(mBackupTarget.appInfo.packageName);
Christopher Tate181fafa2009-05-14 11:12:14 -07004151 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004152 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
4153 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
4154 mBackupTarget.backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -07004155 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004156 Slog.w(TAG, "Exception scheduling backup agent creation: ");
Christopher Tate181fafa2009-05-14 11:12:14 -07004157 e.printStackTrace();
4158 }
4159 }
4160
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004161 if (badApp) {
4162 // todo: Also need to kill application to deal with all
4163 // kinds of exceptions.
Dianne Hackborn130b0d22011-07-26 22:07:48 -07004164 handleAppDiedLocked(app, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004165 return false;
4166 }
4167
4168 if (!didSomething) {
4169 updateOomAdjLocked();
4170 }
4171
4172 return true;
4173 }
4174
4175 public final void attachApplication(IApplicationThread thread) {
4176 synchronized (this) {
4177 int callingPid = Binder.getCallingPid();
4178 final long origId = Binder.clearCallingIdentity();
4179 attachApplicationLocked(thread, callingPid);
4180 Binder.restoreCallingIdentity(origId);
4181 }
4182 }
4183
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004184 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004185 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004186 ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
4187 if (stopProfiling) {
4188 synchronized (this) {
4189 if (mProfileProc == r.app) {
4190 if (mProfileFd != null) {
4191 try {
4192 mProfileFd.close();
4193 } catch (IOException e) {
4194 }
4195 clearProfilerLocked();
4196 }
4197 }
4198 }
4199 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004200 Binder.restoreCallingIdentity(origId);
4201 }
4202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004203 void enableScreenAfterBoot() {
Doug Zongker2bec3d42009-12-04 12:52:44 -08004204 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004205 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206 mWindowManager.enableScreenAfterBoot();
Jeff Brownc042ee22012-05-08 13:03:42 -07004207
4208 synchronized (this) {
4209 updateEventDispatchingLocked();
4210 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004211 }
4212
Dianne Hackborn661cd522011-08-22 00:26:20 -07004213 public void showBootMessage(final CharSequence msg, final boolean always) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004214 enforceNotIsolatedCaller("showBootMessage");
Dianne Hackborn661cd522011-08-22 00:26:20 -07004215 mWindowManager.showBootMessage(msg, always);
4216 }
4217
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004218 public void dismissKeyguardOnNextActivity() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004219 enforceNotIsolatedCaller("dismissKeyguardOnNextActivity");
Jeff Sharkey7ffaa982012-04-30 16:59:05 -07004220 final long token = Binder.clearCallingIdentity();
4221 try {
4222 synchronized (this) {
4223 if (mLockScreenShown) {
4224 mLockScreenShown = false;
4225 comeOutOfSleepIfNeededLocked();
4226 }
4227 mMainStack.dismissKeyguardOnNextActivityLocked();
Dianne Hackborn1e88e982012-04-24 18:35:55 -07004228 }
Jeff Sharkey7ffaa982012-04-30 16:59:05 -07004229 } finally {
4230 Binder.restoreCallingIdentity(token);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07004231 }
4232 }
4233
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004234 final void finishBooting() {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004235 IntentFilter pkgFilter = new IntentFilter();
4236 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
4237 pkgFilter.addDataScheme("package");
4238 mContext.registerReceiver(new BroadcastReceiver() {
4239 @Override
4240 public void onReceive(Context context, Intent intent) {
4241 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
4242 if (pkgs != null) {
4243 for (String pkg : pkgs) {
Vairavan Srinivasan61f07652010-07-22 13:36:40 -07004244 synchronized (ActivityManagerService.this) {
Amith Yamasani483f3b02012-03-13 16:08:00 -07004245 if (forceStopPackageLocked(pkg, -1, false, false, false, false, 0)) {
4246 setResultCode(Activity.RESULT_OK);
4247 return;
4248 }
4249 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004250 }
4251 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004252 }
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004253 }, pkgFilter);
Amith Yamasani13593602012-03-22 16:16:17 -07004254
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004255 synchronized (this) {
4256 // Ensure that any processes we had put on hold are now started
4257 // up.
4258 final int NP = mProcessesOnHold.size();
4259 if (NP > 0) {
4260 ArrayList<ProcessRecord> procs =
4261 new ArrayList<ProcessRecord>(mProcessesOnHold);
4262 for (int ip=0; ip<NP; ip++) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07004263 if (DEBUG_PROCESSES) Slog.v(TAG, "Starting process on hold: "
4264 + procs.get(ip));
4265 startProcessLocked(procs.get(ip), "on-hold", null);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004266 }
4267 }
4268
4269 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004270 // Start looking for apps that are abusing wake locks.
4271 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004272 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08004273 // Tell anyone interested that we are done booting!
Dianne Hackbornf4c454b2010-08-11 12:47:41 -07004274 SystemProperties.set("sys.boot_completed", "1");
Guang Zhu191713a2012-01-12 12:02:22 -08004275 SystemProperties.set("dev.bootcomplete", "1");
Dianne Hackborn80a4af22012-08-27 19:18:31 -07004276 for (int i=0; i<mStartedUsers.size(); i++) {
4277 UserStartedState uss = mStartedUsers.valueAt(i);
4278 if (uss.mState == UserStartedState.STATE_BOOTING) {
4279 uss.mState = UserStartedState.STATE_RUNNING;
Dianne Hackborn41203752012-08-31 14:05:51 -07004280 final int userId = mStartedUsers.keyAt(i);
4281 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
4282 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
4283 broadcastIntentLocked(null, null, intent,
Dianne Hackborn80a4af22012-08-27 19:18:31 -07004284 null, null, 0, null, null,
4285 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Dianne Hackborn41203752012-08-31 14:05:51 -07004286 false, false, MY_PID, Process.SYSTEM_UID, userId);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07004287 }
Amith Yamasani4860cfc2012-08-08 19:14:18 -07004288 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004289 }
4290 }
4291 }
4292
4293 final void ensureBootCompleted() {
4294 boolean booting;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004295 boolean enableScreen;
4296 synchronized (this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004297 booting = mBooting;
4298 mBooting = false;
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004299 enableScreen = !mBooted;
4300 mBooted = true;
4301 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004302
4303 if (booting) {
4304 finishBooting();
4305 }
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004306
4307 if (enableScreen) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07004308 enableScreenAfterBoot();
4309 }
4310 }
4311
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08004312 public final void activityPaused(IBinder token) {
4313 final long origId = Binder.clearCallingIdentity();
4314 mMainStack.activityPaused(token, false);
4315 Binder.restoreCallingIdentity(origId);
4316 }
4317
4318 public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
4319 CharSequence description) {
4320 if (localLOGV) Slog.v(
4321 TAG, "Activity stopped: token=" + token);
4322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004323 // Refuse possible leaked file descriptors
4324 if (icicle != null && icicle.hasFileDescriptors()) {
4325 throw new IllegalArgumentException("File descriptors passed in Bundle");
4326 }
4327
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004328 ActivityRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004329
4330 final long origId = Binder.clearCallingIdentity();
4331
4332 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004333 r = mMainStack.isInStackLocked(token);
4334 if (r != null) {
4335 r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004336 }
4337 }
4338
4339 if (r != null) {
4340 sendPendingThumbnail(r, null, null, null, false);
4341 }
4342
4343 trimApplications();
4344
4345 Binder.restoreCallingIdentity(origId);
4346 }
4347
4348 public final void activityDestroyed(IBinder token) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004349 if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07004350 mMainStack.activityDestroyed(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 }
4352
4353 public String getCallingPackage(IBinder token) {
4354 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004355 ActivityRecord r = getCallingRecordLocked(token);
Dianne Hackborn9bbcb912009-10-20 15:42:38 -07004356 return r != null && r.app != null ? r.info.packageName : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004357 }
4358 }
4359
4360 public ComponentName getCallingActivity(IBinder token) {
4361 synchronized (this) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004362 ActivityRecord r = getCallingRecordLocked(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004363 return r != null ? r.intent.getComponent() : null;
4364 }
4365 }
4366
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004367 private ActivityRecord getCallingRecordLocked(IBinder token) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004368 ActivityRecord r = mMainStack.isInStackLocked(token);
4369 if (r == null) {
4370 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004371 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004372 return r.resultTo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004373 }
4374
4375 public ComponentName getActivityClassForToken(IBinder token) {
4376 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004377 ActivityRecord r = mMainStack.isInStackLocked(token);
4378 if (r == null) {
4379 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004380 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004381 return r.intent.getComponent();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004382 }
4383 }
4384
4385 public String getPackageForToken(IBinder token) {
4386 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004387 ActivityRecord r = mMainStack.isInStackLocked(token);
4388 if (r == null) {
4389 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004390 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004391 return r.packageName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004392 }
4393 }
4394
4395 public IIntentSender getIntentSender(int type,
4396 String packageName, IBinder token, String resultWho,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004397 int requestCode, Intent[] intents, String[] resolvedTypes,
Dianne Hackborn41203752012-08-31 14:05:51 -07004398 int flags, Bundle options, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004399 enforceNotIsolatedCaller("getIntentSender");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004400 // Refuse possible leaked file descriptors
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004401 if (intents != null) {
4402 if (intents.length < 1) {
4403 throw new IllegalArgumentException("Intents array length must be >= 1");
4404 }
4405 for (int i=0; i<intents.length; i++) {
4406 Intent intent = intents[i];
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004407 if (intent != null) {
4408 if (intent.hasFileDescriptors()) {
4409 throw new IllegalArgumentException("File descriptors passed in Intent");
4410 }
Dianne Hackborna4972e92012-03-14 10:38:05 -07004411 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
Dianne Hackborn52b0ce02011-04-14 13:09:32 -07004412 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
4413 throw new IllegalArgumentException(
4414 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
4415 }
4416 intents[i] = new Intent(intent);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004417 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004418 }
4419 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004420 throw new IllegalArgumentException(
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004421 "Intent array length does not match resolvedTypes length");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004422 }
4423 }
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004424 if (options != null) {
4425 if (options.hasFileDescriptors()) {
4426 throw new IllegalArgumentException("File descriptors passed in options");
4427 }
4428 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07004429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004430 synchronized(this) {
4431 int callingUid = Binder.getCallingUid();
Dianne Hackborn41203752012-08-31 14:05:51 -07004432 userId = handleIncomingUserLocked(Binder.getCallingPid(), callingUid, userId,
4433 false, true, "getIntentSender", null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004434 try {
Jeff Brown10e89712011-07-08 18:52:57 -07004435 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004436 int uid = AppGlobals.getPackageManager()
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004437 .getPackageUid(packageName, UserHandle.getUserId(callingUid));
4438 if (!UserHandle.isSameApp(callingUid, uid)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004439 String msg = "Permission Denial: getIntentSender() from pid="
4440 + Binder.getCallingPid()
4441 + ", uid=" + Binder.getCallingUid()
4442 + ", (need uid=" + uid + ")"
4443 + " is not allowed to send as package " + packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004444 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004445 throw new SecurityException(msg);
4446 }
4447 }
Dianne Hackborn41203752012-08-31 14:05:51 -07004448
4449 return getIntentSenderLocked(type, packageName, callingUid, userId,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004450 token, resultWho, requestCode, intents, resolvedTypes, flags, options);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004451
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452 } catch (RemoteException e) {
4453 throw new SecurityException(e);
4454 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004455 }
4456 }
4457
Dianne Hackborn41203752012-08-31 14:05:51 -07004458 IIntentSender getIntentSenderLocked(int type, String packageName,
4459 int callingUid, int userId, IBinder token, String resultWho,
Dianne Hackborn7a2195c2012-03-19 17:38:00 -07004460 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
4461 Bundle options) {
Amith Yamasani742a6712011-05-04 14:49:28 -07004462 if (DEBUG_MU)
4463 Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004464 ActivityRecord activity = null;
Dianne Hackborna4972e92012-03-14 10:38:05 -07004465 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004466 activity = mMainStack.isInStackLocked(token);
4467 if (activity == null) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004468 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004469 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004470 if (activity.finishing) {
4471 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004472 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004473 }
4474
4475 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
4476 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
4477 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
4478 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
4479 |PendingIntent.FLAG_UPDATE_CURRENT);
4480
4481 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
4482 type, packageName, activity, resultWho,
Dianne Hackborn41203752012-08-31 14:05:51 -07004483 requestCode, intents, resolvedTypes, flags, options, userId);
Dianne Hackborn860755f2010-06-03 18:47:52 -07004484 WeakReference<PendingIntentRecord> ref;
4485 ref = mIntentSenderRecords.get(key);
4486 PendingIntentRecord rec = ref != null ? ref.get() : null;
4487 if (rec != null) {
4488 if (!cancelCurrent) {
4489 if (updateCurrent) {
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004490 if (rec.key.requestIntent != null) {
Adam Powell501d4a52012-04-30 15:03:57 -07004491 rec.key.requestIntent.replaceExtras(intents != null ?
4492 intents[intents.length - 1] : null);
Dianne Hackborn621e17d2010-11-22 15:59:56 -08004493 }
4494 if (intents != null) {
4495 intents[intents.length-1] = rec.key.requestIntent;
4496 rec.key.allIntents = intents;
4497 rec.key.allResolvedTypes = resolvedTypes;
4498 } else {
4499 rec.key.allIntents = null;
4500 rec.key.allResolvedTypes = null;
4501 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004502 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004503 return rec;
4504 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004505 rec.canceled = true;
4506 mIntentSenderRecords.remove(key);
4507 }
4508 if (noCreate) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 return rec;
4510 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07004511 rec = new PendingIntentRecord(this, key, callingUid);
4512 mIntentSenderRecords.put(key, rec.ref);
Dianne Hackborna4972e92012-03-14 10:38:05 -07004513 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07004514 if (activity.pendingResults == null) {
4515 activity.pendingResults
4516 = new HashSet<WeakReference<PendingIntentRecord>>();
4517 }
4518 activity.pendingResults.add(rec.ref);
4519 }
4520 return rec;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004521 }
4522
4523 public void cancelIntentSender(IIntentSender sender) {
4524 if (!(sender instanceof PendingIntentRecord)) {
4525 return;
4526 }
4527 synchronized(this) {
4528 PendingIntentRecord rec = (PendingIntentRecord)sender;
4529 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004530 int uid = AppGlobals.getPackageManager()
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004531 .getPackageUid(rec.key.packageName, UserHandle.getCallingUserId());
4532 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 String msg = "Permission Denial: cancelIntentSender() from pid="
4534 + Binder.getCallingPid()
4535 + ", uid=" + Binder.getCallingUid()
4536 + " is not allowed to cancel packges "
4537 + rec.key.packageName;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004538 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004539 throw new SecurityException(msg);
4540 }
4541 } catch (RemoteException e) {
4542 throw new SecurityException(e);
4543 }
4544 cancelIntentSenderLocked(rec, true);
4545 }
4546 }
4547
4548 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
4549 rec.canceled = true;
4550 mIntentSenderRecords.remove(rec.key);
4551 if (cleanActivity && rec.key.activity != null) {
4552 rec.key.activity.pendingResults.remove(rec.ref);
4553 }
4554 }
4555
4556 public String getPackageForIntentSender(IIntentSender pendingResult) {
4557 if (!(pendingResult instanceof PendingIntentRecord)) {
4558 return null;
4559 }
Brad Fitzpatrickb213d102010-04-19 11:58:52 -07004560 try {
4561 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4562 return res.key.packageName;
4563 } catch (ClassCastException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004564 }
4565 return null;
4566 }
4567
Christopher Tatec4a07d12012-04-06 14:19:13 -07004568 public int getUidForIntentSender(IIntentSender sender) {
4569 if (sender instanceof PendingIntentRecord) {
4570 try {
4571 PendingIntentRecord res = (PendingIntentRecord)sender;
4572 return res.uid;
4573 } catch (ClassCastException e) {
4574 }
4575 }
4576 return -1;
4577 }
4578
Dianne Hackborn6c418d52011-06-29 14:05:33 -07004579 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
4580 if (!(pendingResult instanceof PendingIntentRecord)) {
4581 return false;
4582 }
4583 try {
4584 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4585 if (res.key.allIntents == null) {
4586 return false;
4587 }
4588 for (int i=0; i<res.key.allIntents.length; i++) {
4589 Intent intent = res.key.allIntents[i];
4590 if (intent.getPackage() != null && intent.getComponent() != null) {
4591 return false;
4592 }
4593 }
4594 return true;
4595 } catch (ClassCastException e) {
4596 }
4597 return false;
4598 }
4599
Dianne Hackborn1927ae82012-06-22 15:21:36 -07004600 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
4601 if (!(pendingResult instanceof PendingIntentRecord)) {
4602 return false;
4603 }
4604 try {
4605 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
4606 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
4607 return true;
4608 }
4609 return false;
4610 } catch (ClassCastException e) {
4611 }
4612 return false;
4613 }
4614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004615 public void setProcessLimit(int max) {
4616 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4617 "setProcessLimit()");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004618 synchronized (this) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07004619 mProcessLimit = max < 0 ? ProcessList.MAX_HIDDEN_APPS : max;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004620 mProcessLimitOverride = max;
4621 }
4622 trimApplications();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004623 }
4624
4625 public int getProcessLimit() {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004626 synchronized (this) {
4627 return mProcessLimitOverride;
4628 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004629 }
4630
4631 void foregroundTokenDied(ForegroundToken token) {
4632 synchronized (ActivityManagerService.this) {
4633 synchronized (mPidsSelfLocked) {
4634 ForegroundToken cur
4635 = mForegroundProcesses.get(token.pid);
4636 if (cur != token) {
4637 return;
4638 }
4639 mForegroundProcesses.remove(token.pid);
4640 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
4641 if (pr == null) {
4642 return;
4643 }
4644 pr.forcingToForeground = null;
4645 pr.foregroundServices = false;
4646 }
4647 updateOomAdjLocked();
4648 }
4649 }
4650
4651 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
4652 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
4653 "setProcessForeground()");
4654 synchronized(this) {
4655 boolean changed = false;
4656
4657 synchronized (mPidsSelfLocked) {
4658 ProcessRecord pr = mPidsSelfLocked.get(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004659 if (pr == null && isForeground) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004660 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 return;
4662 }
4663 ForegroundToken oldToken = mForegroundProcesses.get(pid);
4664 if (oldToken != null) {
4665 oldToken.token.unlinkToDeath(oldToken, 0);
4666 mForegroundProcesses.remove(pid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004667 if (pr != null) {
4668 pr.forcingToForeground = null;
4669 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004670 changed = true;
4671 }
4672 if (isForeground && token != null) {
4673 ForegroundToken newToken = new ForegroundToken() {
4674 public void binderDied() {
4675 foregroundTokenDied(this);
4676 }
4677 };
4678 newToken.pid = pid;
4679 newToken.token = token;
4680 try {
4681 token.linkToDeath(newToken, 0);
4682 mForegroundProcesses.put(pid, newToken);
4683 pr.forcingToForeground = token;
4684 changed = true;
4685 } catch (RemoteException e) {
4686 // If the process died while doing this, we will later
4687 // do the cleanup with the process death link.
4688 }
4689 }
4690 }
4691
4692 if (changed) {
4693 updateOomAdjLocked();
4694 }
4695 }
4696 }
4697
4698 // =========================================================
4699 // PERMISSIONS
4700 // =========================================================
4701
4702 static class PermissionController extends IPermissionController.Stub {
4703 ActivityManagerService mActivityManagerService;
4704 PermissionController(ActivityManagerService activityManagerService) {
4705 mActivityManagerService = activityManagerService;
4706 }
4707
4708 public boolean checkPermission(String permission, int pid, int uid) {
4709 return mActivityManagerService.checkPermission(permission, pid,
4710 uid) == PackageManager.PERMISSION_GRANTED;
4711 }
4712 }
4713
4714 /**
4715 * This can be called with or without the global lock held.
4716 */
4717 int checkComponentPermission(String permission, int pid, int uid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08004718 int owningUid, boolean exported) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 // We might be performing an operation on behalf of an indirect binder
4720 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
4721 // client identity accordingly before proceeding.
4722 Identity tlsIdentity = sCallerIdentity.get();
4723 if (tlsIdentity != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004724 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004725 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
4726 uid = tlsIdentity.uid;
4727 pid = tlsIdentity.pid;
4728 }
4729
Dianne Hackborn5320eb82012-05-18 12:05:04 -07004730 if (pid == MY_PID) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004731 return PackageManager.PERMISSION_GRANTED;
4732 }
Dianne Hackborn5320eb82012-05-18 12:05:04 -07004733
4734 return ActivityManager.checkComponentPermission(permission, uid,
4735 owningUid, exported);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004736 }
4737
4738 /**
4739 * As the only public entry point for permissions checking, this method
4740 * can enforce the semantic that requesting a check on a null global
4741 * permission is automatically denied. (Internally a null permission
4742 * string is used when calling {@link #checkComponentPermission} in cases
4743 * when only uid-based security is needed.)
4744 *
4745 * This can be called with or without the global lock held.
4746 */
4747 public int checkPermission(String permission, int pid, int uid) {
4748 if (permission == null) {
4749 return PackageManager.PERMISSION_DENIED;
4750 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004751 return checkComponentPermission(permission, pid, UserHandle.getAppId(uid), -1, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004752 }
4753
4754 /**
4755 * Binder IPC calls go through the public entry point.
4756 * This can be called with or without the global lock held.
4757 */
4758 int checkCallingPermission(String permission) {
4759 return checkPermission(permission,
4760 Binder.getCallingPid(),
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004761 UserHandle.getAppId(Binder.getCallingUid()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004762 }
4763
4764 /**
4765 * This can be called with or without the global lock held.
4766 */
4767 void enforceCallingPermission(String permission, String func) {
4768 if (checkCallingPermission(permission)
4769 == PackageManager.PERMISSION_GRANTED) {
4770 return;
4771 }
4772
4773 String msg = "Permission Denial: " + func + " from pid="
4774 + Binder.getCallingPid()
4775 + ", uid=" + Binder.getCallingUid()
4776 + " requires " + permission;
Joe Onorato8a9b2202010-02-26 18:56:32 -08004777 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004778 throw new SecurityException(msg);
4779 }
4780
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004781 /**
4782 * Determine if UID is holding permissions required to access {@link Uri} in
4783 * the given {@link ProviderInfo}. Final permission checking is always done
4784 * in {@link ContentProvider}.
4785 */
4786 private final boolean checkHoldingPermissionsLocked(
4787 IPackageManager pm, ProviderInfo pi, Uri uri, int uid, int modeFlags) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004788 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4789 "checkHoldingPermissionsLocked: uri=" + uri + " uid=" + uid);
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004790
4791 if (pi.applicationInfo.uid == uid) {
4792 return true;
4793 } else if (!pi.exported) {
4794 return false;
4795 }
4796
4797 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
4798 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004799 try {
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004800 // check if target holds top-level <provider> permissions
4801 if (!readMet && pi.readPermission != null
4802 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
4803 readMet = true;
4804 }
4805 if (!writeMet && pi.writePermission != null
4806 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
4807 writeMet = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004808 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004809
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004810 // track if unprotected read/write is allowed; any denied
4811 // <path-permission> below removes this ability
4812 boolean allowDefaultRead = pi.readPermission == null;
4813 boolean allowDefaultWrite = pi.writePermission == null;
Dianne Hackborn48058e82010-09-27 16:53:23 -07004814
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004815 // check if target holds any <path-permission> that match uri
4816 final PathPermission[] pps = pi.pathPermissions;
4817 if (pps != null) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004818 final String path = uri.getPath();
4819 int i = pps.length;
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004820 while (i > 0 && (!readMet || !writeMet)) {
Dianne Hackborn48058e82010-09-27 16:53:23 -07004821 i--;
4822 PathPermission pp = pps[i];
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004823 if (pp.match(path)) {
4824 if (!readMet) {
4825 final String pprperm = pp.getReadPermission();
4826 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking read perm for "
4827 + pprperm + " for " + pp.getPath()
4828 + ": match=" + pp.match(path)
4829 + " check=" + pm.checkUidPermission(pprperm, uid));
4830 if (pprperm != null) {
4831 if (pm.checkUidPermission(pprperm, uid) == PERMISSION_GRANTED) {
4832 readMet = true;
4833 } else {
4834 allowDefaultRead = false;
4835 }
4836 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004837 }
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004838 if (!writeMet) {
4839 final String ppwperm = pp.getWritePermission();
4840 if (DEBUG_URI_PERMISSION) Slog.v(TAG, "Checking write perm "
4841 + ppwperm + " for " + pp.getPath()
4842 + ": match=" + pp.match(path)
4843 + " check=" + pm.checkUidPermission(ppwperm, uid));
4844 if (ppwperm != null) {
4845 if (pm.checkUidPermission(ppwperm, uid) == PERMISSION_GRANTED) {
4846 writeMet = true;
4847 } else {
4848 allowDefaultWrite = false;
4849 }
4850 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004851 }
4852 }
4853 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07004854 }
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004855
4856 // grant unprotected <provider> read/write, if not blocked by
4857 // <path-permission> above
4858 if (allowDefaultRead) readMet = true;
4859 if (allowDefaultWrite) writeMet = true;
4860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004861 } catch (RemoteException e) {
4862 return false;
4863 }
Dianne Hackborn48058e82010-09-27 16:53:23 -07004864
Jeff Sharkey110a6b62012-03-12 11:12:41 -07004865 return readMet && writeMet;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004866 }
4867
4868 private final boolean checkUriPermissionLocked(Uri uri, int uid,
4869 int modeFlags) {
4870 // Root gets to do everything.
Jeff Brown10e89712011-07-08 18:52:57 -07004871 if (uid == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004872 return true;
4873 }
4874 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(uid);
4875 if (perms == null) return false;
4876 UriPermission perm = perms.get(uri);
4877 if (perm == null) return false;
4878 return (modeFlags&perm.modeFlags) == modeFlags;
4879 }
4880
4881 public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08004882 enforceNotIsolatedCaller("checkUriPermission");
4883
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004884 // Another redirected-binder-call permissions check as in
4885 // {@link checkComponentPermission}.
4886 Identity tlsIdentity = sCallerIdentity.get();
4887 if (tlsIdentity != null) {
4888 uid = tlsIdentity.uid;
4889 pid = tlsIdentity.pid;
4890 }
4891
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004892 uid = UserHandle.getAppId(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004893 // Our own process gets to do everything.
4894 if (pid == MY_PID) {
4895 return PackageManager.PERMISSION_GRANTED;
4896 }
4897 synchronized(this) {
4898 return checkUriPermissionLocked(uri, uid, modeFlags)
4899 ? PackageManager.PERMISSION_GRANTED
4900 : PackageManager.PERMISSION_DENIED;
4901 }
4902 }
4903
Dianne Hackborn39792d22010-08-19 18:01:52 -07004904 /**
4905 * Check if the targetPkg can be granted permission to access uri by
4906 * the callingUid using the given modeFlags. Throws a security exception
4907 * if callingUid is not allowed to do this. Returns the uid of the target
4908 * if the URI permission grant should be performed; returns -1 if it is not
4909 * needed (for example targetPkg already has permission to access the URI).
Dianne Hackborn21c241e2012-03-08 13:57:23 -08004910 * If you already know the uid of the target, you can supply it in
4911 * lastTargetUid else set that to -1.
Dianne Hackborn39792d22010-08-19 18:01:52 -07004912 */
4913 int checkGrantUriPermissionLocked(int callingUid, String targetPkg,
Dianne Hackborn21c241e2012-03-08 13:57:23 -08004914 Uri uri, int modeFlags, int lastTargetUid) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004915 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
4916 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
4917 if (modeFlags == 0) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004918 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 }
4920
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004921 if (targetPkg != null) {
4922 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4923 "Checking grant " + targetPkg + " permission to " + uri);
4924 }
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004925
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004926 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004927
4928 // If this is not a content: uri, we can't do anything with it.
4929 if (!ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08004930 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004931 "Can't grant URI permission for non-content URI: " + uri);
Dianne Hackborn39792d22010-08-19 18:01:52 -07004932 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004933 }
4934
4935 String name = uri.getAuthority();
4936 ProviderInfo pi = null;
Amith Yamasani742a6712011-05-04 14:49:28 -07004937 ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004938 UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004939 if (cpr != null) {
4940 pi = cpr.info;
4941 } else {
4942 try {
4943 pi = pm.resolveContentProvider(name,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004944 PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004945 } catch (RemoteException ex) {
4946 }
4947 }
4948 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07004949 Slog.w(TAG, "No content provider found for permission check: " + uri.toSafeString());
Dianne Hackborn39792d22010-08-19 18:01:52 -07004950 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004951 }
4952
Dianne Hackborn21c241e2012-03-08 13:57:23 -08004953 int targetUid = lastTargetUid;
4954 if (targetUid < 0 && targetPkg != null) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004955 try {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07004956 targetUid = pm.getPackageUid(targetPkg, UserHandle.getUserId(callingUid));
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004957 if (targetUid < 0) {
4958 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4959 "Can't grant URI permission no uid for: " + targetPkg);
4960 return -1;
4961 }
4962 } catch (RemoteException ex) {
Dianne Hackborn39792d22010-08-19 18:01:52 -07004963 return -1;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004965 }
4966
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07004967 if (targetUid >= 0) {
4968 // First... does the target actually need this permission?
4969 if (checkHoldingPermissionsLocked(pm, pi, uri, targetUid, modeFlags)) {
4970 // No need to grant the target this permission.
4971 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
4972 "Target " + targetPkg + " already has full permission to " + uri);
4973 return -1;
4974 }
4975 } else {
4976 // First... there is no target package, so can anyone access it?
4977 boolean allowed = pi.exported;
4978 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
4979 if (pi.readPermission != null) {
4980 allowed = false;
4981 }
4982 }
4983 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
4984 if (pi.writePermission != null) {
4985 allowed = false;
4986 }
4987 }
4988 if (allowed) {
4989 return -1;
4990 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004991 }
4992
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08004993 // Second... is the provider allowing granting of URI permissions?
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004994 if (!pi.grantUriPermissions) {
4995 throw new SecurityException("Provider " + pi.packageName
4996 + "/" + pi.name
4997 + " does not allow granting of Uri permissions (uri "
4998 + uri + ")");
4999 }
5000 if (pi.uriPermissionPatterns != null) {
5001 final int N = pi.uriPermissionPatterns.length;
5002 boolean allowed = false;
5003 for (int i=0; i<N; i++) {
5004 if (pi.uriPermissionPatterns[i] != null
5005 && pi.uriPermissionPatterns[i].match(uri.getPath())) {
5006 allowed = true;
5007 break;
5008 }
5009 }
5010 if (!allowed) {
5011 throw new SecurityException("Provider " + pi.packageName
5012 + "/" + pi.name
5013 + " does not allow granting of permission to path of Uri "
5014 + uri);
5015 }
5016 }
5017
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005018 // Third... does the caller itself have permission to access
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005019 // this uri?
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005020 if (callingUid != Process.myUid()) {
5021 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
5022 if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5023 throw new SecurityException("Uid " + callingUid
5024 + " does not have permission to uri " + uri);
5025 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005026 }
5027 }
5028
Dianne Hackborn39792d22010-08-19 18:01:52 -07005029 return targetUid;
5030 }
5031
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005032 public int checkGrantUriPermission(int callingUid, String targetPkg,
5033 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005034 enforceNotIsolatedCaller("checkGrantUriPermission");
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005035 synchronized(this) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005036 return checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005037 }
5038 }
5039
Dianne Hackborn39792d22010-08-19 18:01:52 -07005040 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg,
5041 Uri uri, int modeFlags, UriPermissionOwner owner) {
5042 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5043 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5044 if (modeFlags == 0) {
5045 return;
5046 }
5047
5048 // So here we are: the caller has the assumed permission
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005049 // to the uri, and the target doesn't. Let's now give this to
5050 // the target.
5051
Joe Onorato8a9b2202010-02-26 18:56:32 -08005052 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn39792d22010-08-19 18:01:52 -07005053 "Granting " + targetPkg + "/" + targetUid + " permission to " + uri);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005054
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005055 HashMap<Uri, UriPermission> targetUris
5056 = mGrantedUriPermissions.get(targetUid);
5057 if (targetUris == null) {
5058 targetUris = new HashMap<Uri, UriPermission>();
5059 mGrantedUriPermissions.put(targetUid, targetUris);
5060 }
5061
5062 UriPermission perm = targetUris.get(uri);
5063 if (perm == null) {
5064 perm = new UriPermission(targetUid, uri);
5065 targetUris.put(uri, perm);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005066 }
Dianne Hackbornb424b632010-08-18 15:59:05 -07005067
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005068 perm.modeFlags |= modeFlags;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005069 if (owner == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005070 perm.globalModeFlags |= modeFlags;
Vairavan Srinivasan91c12c22011-01-21 18:26:06 -08005071 } else {
5072 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
5073 perm.readOwners.add(owner);
5074 owner.addReadPermission(perm);
5075 }
5076 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
5077 perm.writeOwners.add(owner);
5078 owner.addWritePermission(perm);
5079 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005080 }
5081 }
5082
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005083 void grantUriPermissionLocked(int callingUid, String targetPkg, Uri uri,
5084 int modeFlags, UriPermissionOwner owner) {
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005085 if (targetPkg == null) {
5086 throw new NullPointerException("targetPkg");
5087 }
5088
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005089 int targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, uri, modeFlags, -1);
Dianne Hackborn39792d22010-08-19 18:01:52 -07005090 if (targetUid < 0) {
5091 return;
5092 }
5093
5094 grantUriPermissionUncheckedLocked(targetUid, targetPkg, uri, modeFlags, owner);
5095 }
5096
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005097 static class NeededUriGrants extends ArrayList<Uri> {
5098 final String targetPkg;
5099 final int targetUid;
5100 final int flags;
5101
5102 NeededUriGrants(String _targetPkg, int _targetUid, int _flags) {
5103 targetPkg = _targetPkg;
5104 targetUid = _targetUid;
5105 flags = _flags;
5106 }
5107 }
5108
Dianne Hackborn39792d22010-08-19 18:01:52 -07005109 /**
5110 * Like checkGrantUriPermissionLocked, but takes an Intent.
5111 */
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005112 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
5113 String targetPkg, Intent intent, int mode, NeededUriGrants needed) {
Dianne Hackbornb424b632010-08-18 15:59:05 -07005114 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005115 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
5116 + " clip=" + (intent != null ? intent.getClipData() : null)
Dianne Hackbornb424b632010-08-18 15:59:05 -07005117 + " from " + intent + "; flags=0x"
5118 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
5119
Dianne Hackborn90f4aaf2010-09-27 14:58:44 -07005120 if (targetPkg == null) {
5121 throw new NullPointerException("targetPkg");
5122 }
5123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005124 if (intent == null) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005125 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005126 }
5127 Uri data = intent.getData();
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005128 ClipData clip = intent.getClipData();
5129 if (data == null && clip == null) {
5130 return null;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005131 }
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005132 if (data != null) {
5133 int target = checkGrantUriPermissionLocked(callingUid, targetPkg, data,
5134 mode, needed != null ? needed.targetUid : -1);
5135 if (target > 0) {
5136 if (needed == null) {
5137 needed = new NeededUriGrants(targetPkg, target, mode);
5138 }
5139 needed.add(data);
5140 }
5141 }
5142 if (clip != null) {
5143 for (int i=0; i<clip.getItemCount(); i++) {
5144 Uri uri = clip.getItemAt(i).getUri();
5145 if (uri != null) {
5146 int target = -1;
5147 target = checkGrantUriPermissionLocked(callingUid, targetPkg, uri,
5148 mode, needed != null ? needed.targetUid : -1);
5149 if (target > 0) {
5150 if (needed == null) {
5151 needed = new NeededUriGrants(targetPkg, target, mode);
5152 }
5153 needed.add(uri);
5154 }
5155 } else {
5156 Intent clipIntent = clip.getItemAt(i).getIntent();
5157 if (clipIntent != null) {
5158 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
5159 callingUid, targetPkg, clipIntent, mode, needed);
5160 if (newNeeded != null) {
5161 needed = newNeeded;
5162 }
5163 }
5164 }
5165 }
5166 }
5167
5168 return needed;
Dianne Hackborn39792d22010-08-19 18:01:52 -07005169 }
5170
5171 /**
5172 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
5173 */
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005174 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
5175 UriPermissionOwner owner) {
5176 if (needed != null) {
5177 for (int i=0; i<needed.size(); i++) {
5178 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
5179 needed.get(i), needed.flags, owner);
5180 }
5181 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005182 }
5183
5184 void grantUriPermissionFromIntentLocked(int callingUid,
5185 String targetPkg, Intent intent, UriPermissionOwner owner) {
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005186 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
Dianne Hackbornd9781fe2012-03-08 18:04:18 -08005187 intent, intent != null ? intent.getFlags() : 0, null);
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005188 if (needed == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005189 return;
5190 }
Dianne Hackborn39792d22010-08-19 18:01:52 -07005191
Dianne Hackborn21c241e2012-03-08 13:57:23 -08005192 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005193 }
5194
5195 public void grantUriPermission(IApplicationThread caller, String targetPkg,
5196 Uri uri, int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005197 enforceNotIsolatedCaller("grantUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005198 synchronized(this) {
5199 final ProcessRecord r = getRecordForAppLocked(caller);
5200 if (r == null) {
5201 throw new SecurityException("Unable to find app for caller "
5202 + caller
5203 + " when granting permission to uri " + uri);
5204 }
5205 if (targetPkg == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005206 throw new IllegalArgumentException("null target");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005207 }
5208 if (uri == null) {
Dianne Hackborn7e269642010-08-25 19:50:20 -07005209 throw new IllegalArgumentException("null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005210 }
5211
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005212 grantUriPermissionLocked(r.uid, targetPkg, uri, modeFlags,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005213 null);
5214 }
5215 }
5216
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005217 void removeUriPermissionIfNeededLocked(UriPermission perm) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 if ((perm.modeFlags&(Intent.FLAG_GRANT_READ_URI_PERMISSION
5219 |Intent.FLAG_GRANT_WRITE_URI_PERMISSION)) == 0) {
5220 HashMap<Uri, UriPermission> perms
5221 = mGrantedUriPermissions.get(perm.uid);
5222 if (perms != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005223 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005224 "Removing " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005225 perms.remove(perm.uri);
5226 if (perms.size() == 0) {
5227 mGrantedUriPermissions.remove(perm.uid);
5228 }
5229 }
5230 }
5231 }
5232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005233 private void revokeUriPermissionLocked(int callingUid, Uri uri,
5234 int modeFlags) {
5235 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5236 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5237 if (modeFlags == 0) {
5238 return;
5239 }
5240
Joe Onorato8a9b2202010-02-26 18:56:32 -08005241 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005242 "Revoking all granted permissions to " + uri);
5243
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005244 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005245
5246 final String authority = uri.getAuthority();
5247 ProviderInfo pi = null;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07005248 int userId = UserHandle.getUserId(callingUid);
Amith Yamasani483f3b02012-03-13 16:08:00 -07005249 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005250 if (cpr != null) {
5251 pi = cpr.info;
5252 } else {
5253 try {
5254 pi = pm.resolveContentProvider(authority,
Amith Yamasani483f3b02012-03-13 16:08:00 -07005255 PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005256 } catch (RemoteException ex) {
5257 }
5258 }
5259 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005260 Slog.w(TAG, "No content provider found for permission revoke: " + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005261 return;
5262 }
5263
5264 // Does the caller have this permission on the URI?
Dianne Hackborn48058e82010-09-27 16:53:23 -07005265 if (!checkHoldingPermissionsLocked(pm, pi, uri, callingUid, modeFlags)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005266 // Right now, if you are not the original owner of the permission,
5267 // you are not allowed to revoke it.
5268 //if (!checkUriPermissionLocked(uri, callingUid, modeFlags)) {
5269 throw new SecurityException("Uid " + callingUid
5270 + " does not have permission to uri " + uri);
5271 //}
5272 }
5273
5274 // Go through all of the permissions and remove any that match.
5275 final List<String> SEGMENTS = uri.getPathSegments();
5276 if (SEGMENTS != null) {
5277 final int NS = SEGMENTS.size();
5278 int N = mGrantedUriPermissions.size();
5279 for (int i=0; i<N; i++) {
5280 HashMap<Uri, UriPermission> perms
5281 = mGrantedUriPermissions.valueAt(i);
5282 Iterator<UriPermission> it = perms.values().iterator();
5283 toploop:
5284 while (it.hasNext()) {
5285 UriPermission perm = it.next();
5286 Uri targetUri = perm.uri;
5287 if (!authority.equals(targetUri.getAuthority())) {
5288 continue;
5289 }
5290 List<String> targetSegments = targetUri.getPathSegments();
5291 if (targetSegments == null) {
5292 continue;
5293 }
5294 if (targetSegments.size() < NS) {
5295 continue;
5296 }
5297 for (int j=0; j<NS; j++) {
5298 if (!SEGMENTS.get(j).equals(targetSegments.get(j))) {
5299 continue toploop;
5300 }
5301 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08005302 if (DEBUG_URI_PERMISSION) Slog.v(TAG,
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08005303 "Revoking " + perm.uid + " permission to " + perm.uri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005304 perm.clearModes(modeFlags);
5305 if (perm.modeFlags == 0) {
5306 it.remove();
5307 }
5308 }
5309 if (perms.size() == 0) {
5310 mGrantedUriPermissions.remove(
5311 mGrantedUriPermissions.keyAt(i));
5312 N--;
5313 i--;
5314 }
5315 }
5316 }
5317 }
5318
5319 public void revokeUriPermission(IApplicationThread caller, Uri uri,
5320 int modeFlags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005321 enforceNotIsolatedCaller("revokeUriPermission");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005322 synchronized(this) {
5323 final ProcessRecord r = getRecordForAppLocked(caller);
5324 if (r == null) {
5325 throw new SecurityException("Unable to find app for caller "
5326 + caller
5327 + " when revoking permission to uri " + uri);
5328 }
5329 if (uri == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005330 Slog.w(TAG, "revokeUriPermission: null uri");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005331 return;
5332 }
5333
5334 modeFlags &= (Intent.FLAG_GRANT_READ_URI_PERMISSION
5335 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
5336 if (modeFlags == 0) {
5337 return;
5338 }
5339
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005340 final IPackageManager pm = AppGlobals.getPackageManager();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005341
5342 final String authority = uri.getAuthority();
5343 ProviderInfo pi = null;
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005344 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005345 if (cpr != null) {
5346 pi = cpr.info;
5347 } else {
5348 try {
5349 pi = pm.resolveContentProvider(authority,
Amith Yamasani483f3b02012-03-13 16:08:00 -07005350 PackageManager.GET_URI_PERMISSION_PATTERNS, r.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005351 } catch (RemoteException ex) {
5352 }
5353 }
5354 if (pi == null) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -07005355 Slog.w(TAG, "No content provider found for permission revoke: "
5356 + uri.toSafeString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005357 return;
5358 }
5359
Dianne Hackborna0c283e2012-02-09 10:47:01 -08005360 revokeUriPermissionLocked(r.uid, uri, modeFlags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005361 }
5362 }
5363
Dianne Hackborn7e269642010-08-25 19:50:20 -07005364 @Override
5365 public IBinder newUriPermissionOwner(String name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005366 enforceNotIsolatedCaller("newUriPermissionOwner");
Dianne Hackborn7e269642010-08-25 19:50:20 -07005367 synchronized(this) {
5368 UriPermissionOwner owner = new UriPermissionOwner(this, name);
5369 return owner.getExternalTokenLocked();
5370 }
5371 }
5372
5373 @Override
5374 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg,
5375 Uri uri, int modeFlags) {
5376 synchronized(this) {
5377 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5378 if (owner == null) {
5379 throw new IllegalArgumentException("Unknown owner: " + token);
5380 }
5381 if (fromUid != Binder.getCallingUid()) {
5382 if (Binder.getCallingUid() != Process.myUid()) {
5383 // Only system code can grant URI permissions on behalf
5384 // of other users.
5385 throw new SecurityException("nice try");
5386 }
5387 }
5388 if (targetPkg == null) {
5389 throw new IllegalArgumentException("null target");
5390 }
5391 if (uri == null) {
5392 throw new IllegalArgumentException("null uri");
5393 }
5394
5395 grantUriPermissionLocked(fromUid, targetPkg, uri, modeFlags, owner);
5396 }
5397 }
5398
5399 @Override
5400 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode) {
5401 synchronized(this) {
5402 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
5403 if (owner == null) {
5404 throw new IllegalArgumentException("Unknown owner: " + token);
5405 }
5406
5407 if (uri == null) {
5408 owner.removeUriPermissionsLocked(mode);
5409 } else {
5410 owner.removeUriPermissionLocked(uri, mode);
5411 }
5412 }
5413 }
5414
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005415 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
5416 synchronized (this) {
5417 ProcessRecord app =
5418 who != null ? getRecordForAppLocked(who) : null;
5419 if (app == null) return;
5420
5421 Message msg = Message.obtain();
5422 msg.what = WAIT_FOR_DEBUGGER_MSG;
5423 msg.obj = app;
5424 msg.arg1 = waiting ? 1 : 0;
5425 mHandler.sendMessage(msg);
5426 }
5427 }
5428
5429 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07005430 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
5431 final long hiddenAppMem = mProcessList.getMemLevel(ProcessList.HIDDEN_APP_MIN_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005432 outInfo.availMem = Process.getFreeMemory();
Dianne Hackborn59325eb2012-05-09 18:45:20 -07005433 outInfo.totalMem = Process.getTotalMemory();
Dianne Hackborn7d608422011-08-07 16:24:18 -07005434 outInfo.threshold = homeAppMem;
5435 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((hiddenAppMem-homeAppMem)/2));
5436 outInfo.hiddenAppThreshold = hiddenAppMem;
5437 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
Dianne Hackborne02c88a2011-10-28 13:58:15 -07005438 ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07005439 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
5440 ProcessList.VISIBLE_APP_ADJ);
5441 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
5442 ProcessList.FOREGROUND_APP_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005443 }
5444
5445 // =========================================================
5446 // TASK MANAGEMENT
5447 // =========================================================
5448
5449 public List getTasks(int maxNum, int flags,
5450 IThumbnailReceiver receiver) {
5451 ArrayList list = new ArrayList();
5452
5453 PendingThumbnailsRecord pending = null;
5454 IApplicationThread topThumbnail = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005455 ActivityRecord topRecord = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005456
5457 synchronized(this) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005458 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005459 TAG, "getTasks: max=" + maxNum + ", flags=" + flags
5460 + ", receiver=" + receiver);
5461
5462 if (checkCallingPermission(android.Manifest.permission.GET_TASKS)
5463 != PackageManager.PERMISSION_GRANTED) {
5464 if (receiver != null) {
5465 // If the caller wants to wait for pending thumbnails,
5466 // it ain't gonna get them.
5467 try {
5468 receiver.finished();
5469 } catch (RemoteException ex) {
5470 }
5471 }
5472 String msg = "Permission Denial: getTasks() from pid="
5473 + Binder.getCallingPid()
5474 + ", uid=" + Binder.getCallingUid()
5475 + " requires " + android.Manifest.permission.GET_TASKS;
Joe Onorato8a9b2202010-02-26 18:56:32 -08005476 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005477 throw new SecurityException(msg);
5478 }
5479
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005480 int pos = mMainStack.mHistory.size()-1;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005481 ActivityRecord next =
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005482 pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005483 ActivityRecord top = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005484 TaskRecord curTask = null;
5485 int numActivities = 0;
5486 int numRunning = 0;
5487 while (pos >= 0 && maxNum > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005488 final ActivityRecord r = next;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005489 pos--;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005490 next = pos >= 0 ? (ActivityRecord)mMainStack.mHistory.get(pos) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005491
5492 // Initialize state for next task if needed.
5493 if (top == null ||
5494 (top.state == ActivityState.INITIALIZING
5495 && top.task == r.task)) {
5496 top = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005497 curTask = r.task;
5498 numActivities = numRunning = 0;
5499 }
5500
5501 // Add 'r' into the current task.
5502 numActivities++;
5503 if (r.app != null && r.app.thread != null) {
5504 numRunning++;
5505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005506
Joe Onorato8a9b2202010-02-26 18:56:32 -08005507 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005508 TAG, r.intent.getComponent().flattenToShortString()
5509 + ": task=" + r.task);
5510
5511 // If the next one is a different task, generate a new
5512 // TaskInfo entry for what we have.
5513 if (next == null || next.task != curTask) {
5514 ActivityManager.RunningTaskInfo ci
5515 = new ActivityManager.RunningTaskInfo();
5516 ci.id = curTask.taskId;
5517 ci.baseActivity = r.intent.getComponent();
5518 ci.topActivity = top.intent.getComponent();
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005519 if (top.thumbHolder != null) {
5520 ci.description = top.thumbHolder.lastDescription;
5521 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522 ci.numActivities = numActivities;
5523 ci.numRunning = numRunning;
5524 //System.out.println(
5525 // "#" + maxNum + ": " + " descr=" + ci.description);
5526 if (ci.thumbnail == null && receiver != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005527 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005528 TAG, "State=" + top.state + "Idle=" + top.idle
5529 + " app=" + top.app
5530 + " thr=" + (top.app != null ? top.app.thread : null));
5531 if (top.state == ActivityState.RESUMED
5532 || top.state == ActivityState.PAUSING) {
5533 if (top.idle && top.app != null
5534 && top.app.thread != null) {
5535 topRecord = top;
5536 topThumbnail = top.app.thread;
5537 } else {
5538 top.thumbnailNeeded = true;
5539 }
5540 }
5541 if (pending == null) {
5542 pending = new PendingThumbnailsRecord(receiver);
5543 }
5544 pending.pendingRecords.add(top);
5545 }
5546 list.add(ci);
5547 maxNum--;
5548 top = null;
5549 }
5550 }
5551
5552 if (pending != null) {
5553 mPendingThumbnails.add(pending);
5554 }
5555 }
5556
Joe Onorato8a9b2202010-02-26 18:56:32 -08005557 if (localLOGV) Slog.v(TAG, "We have pending thumbnails: " + pending);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005558
5559 if (topThumbnail != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005560 if (localLOGV) Slog.v(TAG, "Requesting top thumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005561 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08005562 topThumbnail.requestThumbnail(topRecord.appToken);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005563 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005564 Slog.w(TAG, "Exception thrown when requesting thumbnail", e);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005565 sendPendingThumbnail(null, topRecord.appToken, null, null, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005566 }
5567 }
5568
5569 if (pending == null && receiver != null) {
5570 // In this case all thumbnails were available and the client
5571 // is being asked to be told when the remaining ones come in...
5572 // which is unusually, since the top-most currently running
5573 // activity should never have a canned thumbnail! Oh well.
5574 try {
5575 receiver.finished();
5576 } catch (RemoteException ex) {
5577 }
5578 }
5579
5580 return list;
5581 }
5582
5583 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum,
Amith Yamasani82644082012-08-03 13:09:11 -07005584 int flags, int userId) {
Amith Yamasani742a6712011-05-04 14:49:28 -07005585 final int callingUid = Binder.getCallingUid();
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07005586 if (userId != UserHandle.getCallingUserId()) {
Amith Yamasani82644082012-08-03 13:09:11 -07005587 // Check if the caller is holding permissions for cross-user requests.
5588 if (checkComponentPermission(
5589 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
5590 Binder.getCallingPid(), callingUid, -1, true)
5591 != PackageManager.PERMISSION_GRANTED) {
5592 String msg = "Permission Denial: "
5593 + "Request to get recent tasks for user " + userId
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07005594 + " but is calling from user " + UserHandle.getUserId(callingUid)
Amith Yamasani82644082012-08-03 13:09:11 -07005595 + "; this requires "
5596 + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
5597 Slog.w(TAG, msg);
5598 throw new SecurityException(msg);
5599 } else {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07005600 if (userId == UserHandle.USER_CURRENT) {
Amith Yamasani82644082012-08-03 13:09:11 -07005601 userId = mCurrentUserId;
5602 }
5603 }
5604 }
5605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005606 synchronized (this) {
5607 enforceCallingPermission(android.Manifest.permission.GET_TASKS,
5608 "getRecentTasks()");
Dianne Hackborn8238e712012-04-24 11:15:40 -07005609 final boolean detailed = checkCallingPermission(
5610 android.Manifest.permission.GET_DETAILED_TASKS)
5611 == PackageManager.PERMISSION_GRANTED;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005612
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005613 IPackageManager pm = AppGlobals.getPackageManager();
Amith Yamasani82644082012-08-03 13:09:11 -07005614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005615 final int N = mRecentTasks.size();
5616 ArrayList<ActivityManager.RecentTaskInfo> res
5617 = new ArrayList<ActivityManager.RecentTaskInfo>(
5618 maxNum < N ? maxNum : N);
5619 for (int i=0; i<N && maxNum > 0; i++) {
5620 TaskRecord tr = mRecentTasks.get(i);
Amith Yamasani742a6712011-05-04 14:49:28 -07005621 // Only add calling user's recent tasks
Amith Yamasani82644082012-08-03 13:09:11 -07005622 if (tr.userId != userId) continue;
Dianne Hackborn905577f2011-09-07 18:31:28 -07005623 // Return the entry if desired by the caller. We always return
5624 // the first entry, because callers always expect this to be the
Amith Yamasani742a6712011-05-04 14:49:28 -07005625 // foreground app. We may filter others if the caller has
Dianne Hackborn905577f2011-09-07 18:31:28 -07005626 // not supplied RECENT_WITH_EXCLUDED and there is some reason
5627 // we should exclude the entry.
Amith Yamasani742a6712011-05-04 14:49:28 -07005628
Dianne Hackborn905577f2011-09-07 18:31:28 -07005629 if (i == 0
5630 || ((flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005631 || (tr.intent == null)
5632 || ((tr.intent.getFlags()
5633 &Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS) == 0)) {
5634 ActivityManager.RecentTaskInfo rti
5635 = new ActivityManager.RecentTaskInfo();
5636 rti.id = tr.numActivities > 0 ? tr.taskId : -1;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005637 rti.persistentId = tr.taskId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005638 rti.baseIntent = new Intent(
5639 tr.intent != null ? tr.intent : tr.affinityIntent);
Dianne Hackborn8238e712012-04-24 11:15:40 -07005640 if (!detailed) {
5641 rti.baseIntent.replaceExtras((Bundle)null);
5642 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005643 rti.origActivity = tr.origActivity;
Dianne Hackbornd2835932010-12-13 16:28:46 -08005644 rti.description = tr.lastDescription;
5645
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005646 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0) {
5647 // Check whether this activity is currently available.
5648 try {
5649 if (rti.origActivity != null) {
Amith Yamasani82644082012-08-03 13:09:11 -07005650 if (pm.getActivityInfo(rti.origActivity, 0, userId)
Amith Yamasani483f3b02012-03-13 16:08:00 -07005651 == null) {
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005652 continue;
5653 }
5654 } else if (rti.baseIntent != null) {
5655 if (pm.queryIntentActivities(rti.baseIntent,
Amith Yamasani82644082012-08-03 13:09:11 -07005656 null, 0, userId) == null) {
Dianne Hackborn53d9264d2010-04-13 12:49:14 -07005657 continue;
5658 }
5659 }
5660 } catch (RemoteException e) {
5661 // Will never happen.
5662 }
5663 }
5664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005665 res.add(rti);
5666 maxNum--;
5667 }
5668 }
5669 return res;
5670 }
5671 }
5672
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005673 private TaskRecord taskForIdLocked(int id) {
5674 final int N = mRecentTasks.size();
5675 for (int i=0; i<N; i++) {
5676 TaskRecord tr = mRecentTasks.get(i);
5677 if (tr.taskId == id) {
5678 return tr;
Dianne Hackbornd94df452011-02-16 18:53:31 -08005679 }
5680 }
5681 return null;
5682 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005683
5684 public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
5685 synchronized (this) {
5686 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
5687 "getTaskThumbnails()");
5688 TaskRecord tr = taskForIdLocked(id);
5689 if (tr != null) {
5690 return mMainStack.getTaskThumbnailsLocked(tr);
5691 }
5692 }
5693 return null;
5694 }
5695
5696 public boolean removeSubTask(int taskId, int subTaskIndex) {
5697 synchronized (this) {
5698 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5699 "removeSubTask()");
5700 long ident = Binder.clearCallingIdentity();
5701 try {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005702 return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
5703 true) != null;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005704 } finally {
5705 Binder.restoreCallingIdentity(ident);
5706 }
5707 }
5708 }
5709
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005710 private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
5711 final boolean killProcesses = (flags&ActivityManager.REMOVE_TASK_KILL_PROCESS) != 0;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005712 Intent baseIntent = new Intent(
5713 tr.intent != null ? tr.intent : tr.affinityIntent);
5714 ComponentName component = baseIntent.getComponent();
5715 if (component == null) {
5716 Slog.w(TAG, "Now component for base intent of task: " + tr);
5717 return;
5718 }
5719
5720 // Find any running services associated with this app.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07005721 mServices.cleanUpRemovedTaskLocked(tr, component, baseIntent);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005722
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005723 if (killProcesses) {
5724 // Find any running processes associated with this app.
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005725 final String pkg = component.getPackageName();
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005726 ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>();
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005727 HashMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
5728 for (SparseArray<ProcessRecord> uids : pmap.values()) {
5729 for (int i=0; i<uids.size(); i++) {
5730 ProcessRecord proc = uids.valueAt(i);
5731 if (proc.userId != tr.userId) {
5732 continue;
5733 }
5734 if (!proc.pkgList.contains(pkg)) {
5735 continue;
5736 }
5737 procs.add(proc);
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005738 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005739 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005740
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005741 // Kill the running processes.
5742 for (int i=0; i<procs.size(); i++) {
5743 ProcessRecord pr = procs.get(i);
5744 if (pr.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
5745 Slog.i(TAG, "Killing " + pr.toShortString() + ": remove task");
5746 EventLog.writeEvent(EventLogTags.AM_KILL, pr.pid,
5747 pr.processName, pr.setAdj, "remove task");
Dianne Hackborn45a25bc2012-06-28 13:49:17 -07005748 pr.killedBackground = true;
Dianne Hackborn8894cc52011-07-01 16:28:17 -07005749 Process.killProcessQuiet(pr.pid);
5750 } else {
5751 pr.waitingToKill = "remove task";
5752 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005753 }
5754 }
5755 }
5756
5757 public boolean removeTask(int taskId, int flags) {
5758 synchronized (this) {
5759 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
5760 "removeTask()");
5761 long ident = Binder.clearCallingIdentity();
5762 try {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005763 ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
5764 false);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005765 if (r != null) {
5766 mRecentTasks.remove(r.task);
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005767 cleanUpRemovedTaskLocked(r.task, flags);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005768 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005769 } else {
5770 TaskRecord tr = null;
5771 int i=0;
5772 while (i < mRecentTasks.size()) {
5773 TaskRecord t = mRecentTasks.get(i);
5774 if (t.taskId == taskId) {
5775 tr = t;
5776 break;
5777 }
5778 i++;
5779 }
5780 if (tr != null) {
5781 if (tr.numActivities <= 0) {
5782 // Caller is just removing a recent task that is
5783 // not actively running. That is easy!
5784 mRecentTasks.remove(i);
Dianne Hackborn9da2d402012-03-15 13:43:08 -07005785 cleanUpRemovedTaskLocked(tr, flags);
5786 return true;
Dianne Hackborneeb1dca2011-09-08 13:30:11 -07005787 } else {
5788 Slog.w(TAG, "removeTask: task " + taskId
5789 + " does not have activities to remove, "
5790 + " but numActivities=" + tr.numActivities
5791 + ": " + tr);
5792 }
5793 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005794 }
5795 } finally {
5796 Binder.restoreCallingIdentity(ident);
5797 }
5798 }
5799 return false;
5800 }
Dianne Hackbornd94df452011-02-16 18:53:31 -08005801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005802 private final int findAffinityTaskTopLocked(int startIndex, String affinity) {
5803 int j;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005804 TaskRecord startTask = ((ActivityRecord)mMainStack.mHistory.get(startIndex)).task;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005805 TaskRecord jt = startTask;
5806
5807 // First look backwards
5808 for (j=startIndex-1; j>=0; j--) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005809 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005810 if (r.task != jt) {
5811 jt = r.task;
5812 if (affinity.equals(jt.affinity)) {
5813 return j;
5814 }
5815 }
5816 }
5817
5818 // Now look forwards
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005819 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005820 jt = startTask;
5821 for (j=startIndex+1; j<N; j++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005822 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(j);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005823 if (r.task != jt) {
5824 if (affinity.equals(jt.affinity)) {
5825 return j;
5826 }
5827 jt = r.task;
5828 }
5829 }
5830
5831 // Might it be at the top?
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005832 if (affinity.equals(((ActivityRecord)mMainStack.mHistory.get(N-1)).task.affinity)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005833 return N-1;
5834 }
5835
5836 return -1;
5837 }
5838
5839 /**
Dianne Hackbornb06ea702009-07-13 13:07:51 -07005840 * TODO: Add mController hook
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005841 */
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005842 public void moveTaskToFront(int task, int flags, Bundle options) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005843 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5844 "moveTaskToFront()");
5845
5846 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005847 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5848 Binder.getCallingUid(), "Task to front")) {
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005849 ActivityOptions.abort(options);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005850 return;
5851 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005852 final long origId = Binder.clearCallingIdentity();
5853 try {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005854 TaskRecord tr = taskForIdLocked(task);
5855 if (tr != null) {
5856 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5857 mMainStack.mUserLeaving = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005858 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005859 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5860 // Caller wants the home activity moved with it. To accomplish this,
5861 // we'll just move the home task to the top first.
5862 mMainStack.moveHomeToFrontLocked();
5863 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005864 mMainStack.moveTaskToFrontLocked(tr, null, options);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07005865 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005866 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005867 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
5868 ActivityRecord hr = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005869 if (hr.task.taskId == task) {
Dianne Hackbornd94df452011-02-16 18:53:31 -08005870 if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
5871 mMainStack.mUserLeaving = true;
5872 }
Dianne Hackborn621e17d2010-11-22 15:59:56 -08005873 if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
5874 // Caller wants the home activity moved with it. To accomplish this,
5875 // we'll just move the home task to the top first.
5876 mMainStack.moveHomeToFrontLocked();
5877 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005878 mMainStack.moveTaskToFrontLocked(hr.task, null, options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005879 return;
5880 }
5881 }
5882 } finally {
5883 Binder.restoreCallingIdentity(origId);
5884 }
Dianne Hackborn8078d8c2012-03-20 11:11:26 -07005885 ActivityOptions.abort(options);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005886 }
5887 }
5888
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005889 public void moveTaskToBack(int task) {
5890 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5891 "moveTaskToBack()");
5892
5893 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005894 if (mMainStack.mResumedActivity != null
5895 && mMainStack.mResumedActivity.task.taskId == task) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005896 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5897 Binder.getCallingUid(), "Task to back")) {
5898 return;
5899 }
5900 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005901 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005902 mMainStack.moveTaskToBackLocked(task, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005903 Binder.restoreCallingIdentity(origId);
5904 }
5905 }
5906
5907 /**
5908 * Moves an activity, and all of the other activities within the same task, to the bottom
5909 * of the history stack. The activity's order within the task is unchanged.
5910 *
5911 * @param token A reference to the activity we wish to move
5912 * @param nonRoot If false then this only works if the activity is the root
5913 * of a task; if true it will work for any activity in a task.
5914 * @return Returns true if the move completed, false if not.
5915 */
5916 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08005917 enforceNotIsolatedCaller("moveActivityTaskToBack");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005918 synchronized(this) {
5919 final long origId = Binder.clearCallingIdentity();
5920 int taskId = getTaskForActivityLocked(token, !nonRoot);
5921 if (taskId >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005922 return mMainStack.moveTaskToBackLocked(taskId, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005923 }
5924 Binder.restoreCallingIdentity(origId);
5925 }
5926 return false;
5927 }
5928
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005929 public void moveTaskBackwards(int task) {
5930 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
5931 "moveTaskBackwards()");
5932
5933 synchronized(this) {
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07005934 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
5935 Binder.getCallingUid(), "Task backwards")) {
5936 return;
5937 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005938 final long origId = Binder.clearCallingIdentity();
5939 moveTaskBackwardsLocked(task);
5940 Binder.restoreCallingIdentity(origId);
5941 }
5942 }
5943
5944 private final void moveTaskBackwardsLocked(int task) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08005945 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005946 }
5947
5948 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
5949 synchronized(this) {
5950 return getTaskForActivityLocked(token, onlyRoot);
5951 }
5952 }
5953
5954 int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005955 final int N = mMainStack.mHistory.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005956 TaskRecord lastTask = null;
5957 for (int i=0; i<N; i++) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07005958 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
Dianne Hackbornbe707852011-11-11 14:32:10 -08005959 if (r.appToken == token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005960 if (!onlyRoot || lastTask != r.task) {
5961 return r.task.taskId;
5962 }
5963 return -1;
5964 }
5965 lastTask = r.task;
5966 }
5967
5968 return -1;
5969 }
5970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005971 // =========================================================
5972 // THUMBNAILS
5973 // =========================================================
5974
5975 public void reportThumbnail(IBinder token,
5976 Bitmap thumbnail, CharSequence description) {
5977 //System.out.println("Report thumbnail for " + token + ": " + thumbnail);
5978 final long origId = Binder.clearCallingIdentity();
5979 sendPendingThumbnail(null, token, thumbnail, description, true);
5980 Binder.restoreCallingIdentity(origId);
5981 }
5982
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07005983 final void sendPendingThumbnail(ActivityRecord r, IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005984 Bitmap thumbnail, CharSequence description, boolean always) {
5985 TaskRecord task = null;
5986 ArrayList receivers = null;
5987
5988 //System.out.println("Send pending thumbnail: " + r);
5989
5990 synchronized(this) {
5991 if (r == null) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07005992 r = mMainStack.isInStackLocked(token);
5993 if (r == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005994 return;
5995 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07005997 if (thumbnail == null && r.thumbHolder != null) {
5998 thumbnail = r.thumbHolder.lastThumbnail;
5999 description = r.thumbHolder.lastDescription;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006000 }
6001 if (thumbnail == null && !always) {
6002 // If there is no thumbnail, and this entry is not actually
6003 // going away, then abort for now and pick up the next
6004 // thumbnail we get.
6005 return;
6006 }
6007 task = r.task;
6008
6009 int N = mPendingThumbnails.size();
6010 int i=0;
6011 while (i<N) {
6012 PendingThumbnailsRecord pr =
6013 (PendingThumbnailsRecord)mPendingThumbnails.get(i);
6014 //System.out.println("Looking in " + pr.pendingRecords);
6015 if (pr.pendingRecords.remove(r)) {
6016 if (receivers == null) {
6017 receivers = new ArrayList();
6018 }
6019 receivers.add(pr);
6020 if (pr.pendingRecords.size() == 0) {
6021 pr.finished = true;
6022 mPendingThumbnails.remove(i);
6023 N--;
6024 continue;
6025 }
6026 }
6027 i++;
6028 }
6029 }
6030
6031 if (receivers != null) {
6032 final int N = receivers.size();
6033 for (int i=0; i<N; i++) {
6034 try {
6035 PendingThumbnailsRecord pr =
6036 (PendingThumbnailsRecord)receivers.get(i);
6037 pr.receiver.newThumbnail(
6038 task != null ? task.taskId : -1, thumbnail, description);
6039 if (pr.finished) {
6040 pr.receiver.finished();
6041 }
6042 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006043 Slog.w(TAG, "Exception thrown when sending thumbnail", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006044 }
6045 }
6046 }
6047 }
6048
6049 // =========================================================
6050 // CONTENT PROVIDERS
6051 // =========================================================
6052
Jeff Brown10e89712011-07-08 18:52:57 -07006053 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
6054 List<ProviderInfo> providers = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006055 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006056 providers = AppGlobals.getPackageManager().
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006057 queryContentProviders(app.processName, app.uid,
Dianne Hackborn1655be42009-05-08 14:29:01 -07006058 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006059 } catch (RemoteException ex) {
6060 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006061 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006062 Slog.v(TAG_MU, "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
6063 int userId = app.userId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006064 if (providers != null) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006065 int N = providers.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006066 for (int i=0; i<N; i++) {
6067 ProviderInfo cpi =
6068 (ProviderInfo)providers.get(i);
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006069 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6070 cpi.name, cpi.flags);
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07006071 if (singleton && UserHandle.getUserId(app.uid) != 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006072 // This is a singleton provider, but a user besides the
6073 // default user is asking to initialize a process it runs
6074 // in... well, no, it doesn't actually run in this process,
6075 // it runs in the process of the default user. Get rid of it.
6076 providers.remove(i);
6077 N--;
6078 continue;
6079 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006080
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006081 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006082 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006083 if (cpr == null) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006084 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
Amith Yamasani742a6712011-05-04 14:49:28 -07006085 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006086 }
Amith Yamasani742a6712011-05-04 14:49:28 -07006087 if (DEBUG_MU)
6088 Slog.v(TAG_MU, "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006089 app.pubProviders.put(cpi.name, cpr);
6090 app.addPackage(cpi.applicationInfo.packageName);
Dianne Hackborn5c1e00b2009-06-18 17:10:57 -07006091 ensurePackageDexOpt(cpi.applicationInfo.packageName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006092 }
6093 }
6094 return providers;
6095 }
6096
Jeff Sharkey110a6b62012-03-12 11:12:41 -07006097 /**
6098 * Check if {@link ProcessRecord} has a possible chance at accessing the
6099 * given {@link ProviderInfo}. Final permission checking is always done
6100 * in {@link ContentProvider}.
6101 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006102 private final String checkContentProviderPermissionLocked(
Dianne Hackbornb424b632010-08-18 15:59:05 -07006103 ProviderInfo cpi, ProcessRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006104 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006105 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006107 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006108 == PackageManager.PERMISSION_GRANTED) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 return null;
6110 }
6111 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006112 cpi.applicationInfo.uid, cpi.exported)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006113 == PackageManager.PERMISSION_GRANTED) {
6114 return null;
6115 }
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006116
6117 PathPermission[] pps = cpi.pathPermissions;
6118 if (pps != null) {
6119 int i = pps.length;
6120 while (i > 0) {
6121 i--;
6122 PathPermission pp = pps[i];
6123 if (checkComponentPermission(pp.getReadPermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006124 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackbornb424b632010-08-18 15:59:05 -07006125 == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006126 return null;
6127 }
6128 if (checkComponentPermission(pp.getWritePermission(), callingPid, callingUid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006129 cpi.applicationInfo.uid, cpi.exported)
Dianne Hackborn2af632f2009-07-08 14:56:37 -07006130 == PackageManager.PERMISSION_GRANTED) {
6131 return null;
6132 }
6133 }
6134 }
6135
Dianne Hackbornb424b632010-08-18 15:59:05 -07006136 HashMap<Uri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
6137 if (perms != null) {
6138 for (Map.Entry<Uri, UriPermission> uri : perms.entrySet()) {
6139 if (uri.getKey().getAuthority().equals(cpi.authority)) {
6140 return null;
6141 }
6142 }
6143 }
6144
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08006145 String msg;
6146 if (!cpi.exported) {
6147 msg = "Permission Denial: opening provider " + cpi.name
6148 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6149 + ", uid=" + callingUid + ") that is not exported from uid "
6150 + cpi.applicationInfo.uid;
6151 } else {
6152 msg = "Permission Denial: opening provider " + cpi.name
6153 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
6154 + ", uid=" + callingUid + ") requires "
6155 + cpi.readPermission + " or " + cpi.writePermission;
6156 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08006157 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006158 return msg;
6159 }
6160
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006161 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
6162 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006163 if (r != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006164 for (int i=0; i<r.conProviders.size(); i++) {
6165 ContentProviderConnection conn = r.conProviders.get(i);
6166 if (conn.provider == cpr) {
6167 if (DEBUG_PROVIDER) Slog.v(TAG,
6168 "Adding provider requested by "
6169 + r.processName + " from process "
6170 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
6171 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6172 if (stable) {
6173 conn.stableCount++;
6174 conn.numStableIncs++;
6175 } else {
6176 conn.unstableCount++;
6177 conn.numUnstableIncs++;
6178 }
6179 return conn;
6180 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006181 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006182 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
6183 if (stable) {
6184 conn.stableCount = 1;
6185 conn.numStableIncs = 1;
6186 } else {
6187 conn.unstableCount = 1;
6188 conn.numUnstableIncs = 1;
6189 }
6190 cpr.connections.add(conn);
6191 r.conProviders.add(conn);
6192 return conn;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006193 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006194 cpr.addExternalProcessHandleLocked(externalProcessToken);
6195 return null;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006196 }
6197
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006198 boolean decProviderCountLocked(ContentProviderConnection conn,
6199 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
6200 if (conn != null) {
6201 cpr = conn.provider;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006202 if (DEBUG_PROVIDER) Slog.v(TAG,
6203 "Removing provider requested by "
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006204 + conn.client.processName + " from process "
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006205 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006206 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
6207 if (stable) {
6208 conn.stableCount--;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006209 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006210 conn.unstableCount--;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006211 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006212 if (conn.stableCount == 0 && conn.unstableCount == 0) {
6213 cpr.connections.remove(conn);
6214 conn.client.conProviders.remove(conn);
6215 return true;
6216 }
6217 return false;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006218 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006219 cpr.removeExternalProcessHandleLocked(externalProcessToken);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006220 return false;
6221 }
6222
Amith Yamasani742a6712011-05-04 14:49:28 -07006223 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
Dianne Hackborn41203752012-08-31 14:05:51 -07006224 String name, IBinder token, boolean stable, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006225 ContentProviderRecord cpr;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006226 ContentProviderConnection conn = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006227 ProviderInfo cpi = null;
6228
6229 synchronized(this) {
6230 ProcessRecord r = null;
6231 if (caller != null) {
6232 r = getRecordForAppLocked(caller);
6233 if (r == null) {
6234 throw new SecurityException(
6235 "Unable to find app for caller " + caller
6236 + " (pid=" + Binder.getCallingPid()
6237 + ") when getting content provider " + name);
6238 }
Dianne Hackborn41203752012-08-31 14:05:51 -07006239 if (r.userId != userId) {
6240 throw new SecurityException("Calling requested user " + userId
6241 + " but app is user " + r.userId);
6242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006243 }
6244
6245 // First check if this content provider has been published...
Amith Yamasani742a6712011-05-04 14:49:28 -07006246 cpr = mProviderMap.getProviderByName(name, userId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006247 boolean providerRunning = cpr != null;
6248 if (providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006249 cpi = cpr.info;
Dianne Hackbornb424b632010-08-18 15:59:05 -07006250 String msg;
6251 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6252 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006253 }
6254
6255 if (r != null && cpr.canRunHere(r)) {
6256 // This provider has been published or is in the process
6257 // of being published... but it is also allowed to run
6258 // in the caller's process, so don't make a connection
6259 // and just let the caller instantiate its own instance.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006260 ContentProviderHolder holder = cpr.newHolder(null);
6261 // don't give caller the provider object, it needs
6262 // to make its own.
6263 holder.provider = null;
6264 return holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006265 }
6266
6267 final long origId = Binder.clearCallingIdentity();
6268
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006269 // In this case the provider instance already exists, so we can
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006270 // return it right away.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006271 conn = incProviderCountLocked(r, cpr, token, stable);
6272 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006273 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn32907cf2010-06-10 17:50:20 -07006274 // If this is a perceptible app accessing the provider,
Dianne Hackborn906497c2010-05-10 15:57:38 -07006275 // make sure to count it as being accessed and thus
6276 // back up on the LRU list. This is good because
6277 // content providers are often expensive to start.
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006278 updateLruProcessLocked(cpr.proc, false, true);
Dianne Hackborn906497c2010-05-10 15:57:38 -07006279 }
Dianne Hackborn6f86c0e2010-05-11 14:20:52 -07006280 }
6281
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006282 if (cpr.proc != null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006283 if (false) {
6284 if (cpr.name.flattenToShortString().equals(
6285 "com.android.providers.calendar/.CalendarProvider2")) {
6286 Slog.v(TAG, "****************** KILLING "
6287 + cpr.name.flattenToShortString());
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006288 Process.killProcess(cpr.proc.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006289 }
6290 }
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006291 boolean success = updateOomAdjLocked(cpr.proc);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006292 if (DEBUG_PROVIDER) Slog.i(TAG, "Adjust success: " + success);
6293 // NOTE: there is still a race here where a signal could be
6294 // pending on the process even though we managed to update its
6295 // adj level. Not sure what to do about this, but at least
6296 // the race is now smaller.
6297 if (!success) {
6298 // Uh oh... it looks like the provider's process
6299 // has been killed on us. We need to wait for a new
6300 // process to be started, and make sure its death
6301 // doesn't kill our process.
6302 Slog.i(TAG,
6303 "Existing provider " + cpr.name.flattenToShortString()
6304 + " is crashing; detaching " + r);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006305 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006306 appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006307 if (!lastRef) {
6308 // This wasn't the last ref our process had on
6309 // the provider... we have now been killed, bail.
6310 return null;
6311 }
6312 providerRunning = false;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006313 conn = null;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006314 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006315 }
6316
6317 Binder.restoreCallingIdentity(origId);
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006318 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006319
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006320 boolean singleton;
Dianne Hackborn295e3c22011-08-25 13:19:08 -07006321 if (!providerRunning) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006322 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006323 cpi = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07006324 resolveContentProvider(name,
Amith Yamasani483f3b02012-03-13 16:08:00 -07006325 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006326 } catch (RemoteException ex) {
6327 }
6328 if (cpi == null) {
6329 return null;
6330 }
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006331 singleton = isSingleton(cpi.processName, cpi.applicationInfo,
6332 cpi.name, cpi.flags);
6333 if (singleton) {
Amith Yamasania4a54e22012-04-16 15:44:19 -07006334 userId = 0;
6335 }
Amith Yamasani483f3b02012-03-13 16:08:00 -07006336 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
Amith Yamasani742a6712011-05-04 14:49:28 -07006337
Dianne Hackbornb424b632010-08-18 15:59:05 -07006338 String msg;
6339 if ((msg=checkContentProviderPermissionLocked(cpi, r)) != null) {
6340 throw new SecurityException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006341 }
6342
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07006343 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006344 && !cpi.processName.equals("system")) {
6345 // If this content provider does not run in the system
6346 // process, and the system is not yet ready to run other
6347 // processes, then fail fast instead of hanging.
6348 throw new IllegalArgumentException(
6349 "Attempt to launch content provider before system ready");
6350 }
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006351
Dianne Hackborn80a4af22012-08-27 19:18:31 -07006352 // Make sure that the user who owns this provider is started. If not,
6353 // we don't want to allow it to run.
6354 if (mStartedUsers.get(userId) == null) {
6355 Slog.w(TAG, "Unable to launch app "
6356 + cpi.applicationInfo.packageName + "/"
6357 + cpi.applicationInfo.uid + " for provider "
6358 + name + ": user " + userId + " is stopped");
6359 return null;
6360 }
6361
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006362 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
Amith Yamasani483f3b02012-03-13 16:08:00 -07006363 cpr = mProviderMap.getProviderByClass(comp, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006364 final boolean firstClass = cpr == null;
6365 if (firstClass) {
6366 try {
6367 ApplicationInfo ai =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07006368 AppGlobals.getPackageManager().
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006369 getApplicationInfo(
6370 cpi.applicationInfo.packageName,
Amith Yamasani483f3b02012-03-13 16:08:00 -07006371 STOCK_PM_FLAGS, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006372 if (ai == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006373 Slog.w(TAG, "No package info for content provider "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006374 + cpi.name);
6375 return null;
6376 }
Amith Yamasani483f3b02012-03-13 16:08:00 -07006377 ai = getAppInfoForUser(ai, userId);
Dianne Hackborn7d19e022012-08-07 19:12:33 -07006378 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006379 } catch (RemoteException ex) {
6380 // pm is in same process, this will never happen.
6381 }
6382 }
6383
6384 if (r != null && cpr.canRunHere(r)) {
6385 // If this is a multiprocess provider, then just return its
6386 // info and allow the caller to instantiate it. Only do
6387 // this if the provider is the same user as the caller's
6388 // process, or can run as root (so can be in any process).
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006389 return cpr.newHolder(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006390 }
6391
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006392 if (DEBUG_PROVIDER) {
6393 RuntimeException e = new RuntimeException("here");
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006394 Slog.w(TAG, "LAUNCHING REMOTE PROVIDER (myuid " + r.uid
Dianne Hackborna1e989b2009-09-01 19:54:29 -07006395 + " pruid " + cpr.appInfo.uid + "): " + cpr.info.name, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006396 }
6397
6398 // This is single process, and our app is now connecting to it.
6399 // See if we are already in the process of launching this
6400 // provider.
6401 final int N = mLaunchingProviders.size();
6402 int i;
6403 for (i=0; i<N; i++) {
6404 if (mLaunchingProviders.get(i) == cpr) {
6405 break;
6406 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006407 }
6408
6409 // If the provider is not already being launched, then get it
6410 // started.
6411 if (i >= N) {
6412 final long origId = Binder.clearCallingIdentity();
Dianne Hackborne7f97212011-02-24 14:40:20 -08006413
6414 try {
6415 // Content provider is now in use, its package can't be stopped.
6416 try {
6417 AppGlobals.getPackageManager().setPackageStoppedState(
Amith Yamasani483f3b02012-03-13 16:08:00 -07006418 cpr.appInfo.packageName, false, userId);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006419 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006420 } catch (IllegalArgumentException e) {
6421 Slog.w(TAG, "Failed trying to unstop package "
6422 + cpr.appInfo.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006423 }
6424
6425 ProcessRecord proc = startProcessLocked(cpi.processName,
6426 cpr.appInfo, false, 0, "content provider",
6427 new ComponentName(cpi.applicationInfo.packageName,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006428 cpi.name), false, false);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006429 if (proc == null) {
6430 Slog.w(TAG, "Unable to launch app "
6431 + cpi.applicationInfo.packageName + "/"
6432 + cpi.applicationInfo.uid + " for provider "
6433 + name + ": process is bad");
6434 return null;
6435 }
6436 cpr.launchingApp = proc;
6437 mLaunchingProviders.add(cpr);
6438 } finally {
6439 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006440 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006441 }
6442
6443 // Make sure the provider is published (the same provider class
6444 // may be published under multiple names).
6445 if (firstClass) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006446 mProviderMap.putProviderByClass(comp, cpr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006447 }
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006448
Amith Yamasani742a6712011-05-04 14:49:28 -07006449 mProviderMap.putProviderByName(name, cpr);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006450 conn = incProviderCountLocked(r, cpr, token, stable);
6451 if (conn != null) {
6452 conn.waiting = true;
6453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006454 }
6455 }
6456
6457 // Wait for the provider to be published...
6458 synchronized (cpr) {
6459 while (cpr.provider == null) {
6460 if (cpr.launchingApp == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006461 Slog.w(TAG, "Unable to launch app "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006462 + cpi.applicationInfo.packageName + "/"
6463 + cpi.applicationInfo.uid + " for provider "
6464 + name + ": launching app became null");
Doug Zongker2bec3d42009-12-04 12:52:44 -08006465 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006466 cpi.applicationInfo.packageName,
6467 cpi.applicationInfo.uid, name);
6468 return null;
6469 }
6470 try {
Amith Yamasani742a6712011-05-04 14:49:28 -07006471 if (DEBUG_MU) {
6472 Slog.v(TAG_MU, "Waiting to start provider " + cpr + " launchingApp="
6473 + cpr.launchingApp);
6474 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006475 if (conn != null) {
6476 conn.waiting = true;
6477 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006478 cpr.wait();
6479 } catch (InterruptedException ex) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006480 } finally {
6481 if (conn != null) {
6482 conn.waiting = false;
6483 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006484 }
6485 }
6486 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006487 return cpr != null ? cpr.newHolder(conn) : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006488 }
6489
6490 public final ContentProviderHolder getContentProvider(
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006491 IApplicationThread caller, String name, boolean stable) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006492 enforceNotIsolatedCaller("getContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006493 if (caller == null) {
6494 String msg = "null IApplicationThread when getting content provider "
6495 + name;
Joe Onorato8a9b2202010-02-26 18:56:32 -08006496 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006497 throw new SecurityException(msg);
6498 }
6499
Dianne Hackborn41203752012-08-31 14:05:51 -07006500 return getContentProviderImpl(caller, name, null, stable,
6501 UserHandle.getCallingUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006502 }
6503
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006504 public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
6505 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6506 "Do not have permission in call getContentProviderExternal()");
Dianne Hackborn41203752012-08-31 14:05:51 -07006507 return getContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006508 }
6509
Dianne Hackborn41203752012-08-31 14:05:51 -07006510 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
6511 IBinder token, int userId) {
6512 return getContentProviderImpl(null, name, token, true, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006513 }
6514
6515 /**
6516 * Drop a content provider from a ProcessRecord's bookkeeping
6517 * @param cpr
6518 */
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006519 public void removeContentProvider(IBinder connection, boolean stable) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006520 enforceNotIsolatedCaller("removeContentProvider");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006521 synchronized (this) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006522 ContentProviderConnection conn;
6523 try {
6524 conn = (ContentProviderConnection)connection;
6525 } catch (ClassCastException e) {
6526 String msg ="removeContentProvider: " + connection
6527 + " not a ContentProviderConnection";
6528 Slog.w(TAG, msg);
6529 throw new IllegalArgumentException(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006530 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006531 if (conn == null) {
6532 throw new NullPointerException("connection is null");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006533 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006534 if (decProviderCountLocked(conn, null, null, stable)) {
6535 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006536 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006537 }
6538 }
6539
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006540 public void removeContentProviderExternal(String name, IBinder token) {
6541 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
6542 "Do not have permission in call removeContentProviderExternal()");
Dianne Hackborn41203752012-08-31 14:05:51 -07006543 removeContentProviderExternalUnchecked(name, token, UserHandle.getCallingUserId());
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006544 }
6545
Dianne Hackborn41203752012-08-31 14:05:51 -07006546 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006547 synchronized (this) {
Dianne Hackborn41203752012-08-31 14:05:51 -07006548 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006549 if(cpr == null) {
6550 //remove from mProvidersByClass
Joe Onorato8a9b2202010-02-26 18:56:32 -08006551 if(localLOGV) Slog.v(TAG, name+" content provider not found in providers list");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006552 return;
6553 }
6554
6555 //update content provider record entry info
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006556 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
Dianne Hackborn41203752012-08-31 14:05:51 -07006557 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
Svetoslav Ganov25872aa2012-02-03 19:19:09 -08006558 if (localCpr.hasExternalProcessHandles()) {
6559 if (localCpr.removeExternalProcessHandleLocked(token)) {
6560 updateOomAdjLocked();
6561 } else {
6562 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
6563 + " with no external reference for token: "
6564 + token + ".");
6565 }
6566 } else {
6567 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
6568 + " with no external references.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006569 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006570 }
6571 }
6572
6573 public final void publishContentProviders(IApplicationThread caller,
6574 List<ContentProviderHolder> providers) {
6575 if (providers == null) {
6576 return;
6577 }
6578
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006579 enforceNotIsolatedCaller("publishContentProviders");
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006580 synchronized (this) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006581 final ProcessRecord r = getRecordForAppLocked(caller);
Amith Yamasani742a6712011-05-04 14:49:28 -07006582 if (DEBUG_MU)
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006583 Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006584 if (r == null) {
6585 throw new SecurityException(
6586 "Unable to find app for caller " + caller
6587 + " (pid=" + Binder.getCallingPid()
6588 + ") when publishing content providers");
6589 }
6590
6591 final long origId = Binder.clearCallingIdentity();
6592
6593 final int N = providers.size();
6594 for (int i=0; i<N; i++) {
6595 ContentProviderHolder src = providers.get(i);
6596 if (src == null || src.info == null || src.provider == null) {
6597 continue;
6598 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07006599 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006600 if (DEBUG_MU)
6601 Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006602 if (dst != null) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07006603 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
Amith Yamasani742a6712011-05-04 14:49:28 -07006604 mProviderMap.putProviderByClass(comp, dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006605 String names[] = dst.info.authority.split(";");
6606 for (int j = 0; j < names.length; j++) {
Amith Yamasani742a6712011-05-04 14:49:28 -07006607 mProviderMap.putProviderByName(names[j], dst);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006608 }
6609
6610 int NL = mLaunchingProviders.size();
6611 int j;
6612 for (j=0; j<NL; j++) {
6613 if (mLaunchingProviders.get(j) == dst) {
6614 mLaunchingProviders.remove(j);
6615 j--;
6616 NL--;
6617 }
6618 }
6619 synchronized (dst) {
6620 dst.provider = src.provider;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -07006621 dst.proc = r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006622 dst.notifyAll();
6623 }
6624 updateOomAdjLocked(r);
6625 }
6626 }
6627
6628 Binder.restoreCallingIdentity(origId);
6629 }
6630 }
6631
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006632 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
6633 ContentProviderConnection conn;
6634 try {
6635 conn = (ContentProviderConnection)connection;
6636 } catch (ClassCastException e) {
6637 String msg ="refContentProvider: " + connection
6638 + " not a ContentProviderConnection";
6639 Slog.w(TAG, msg);
6640 throw new IllegalArgumentException(msg);
6641 }
6642 if (conn == null) {
6643 throw new NullPointerException("connection is null");
6644 }
6645
6646 synchronized (this) {
6647 if (stable > 0) {
6648 conn.numStableIncs += stable;
6649 }
6650 stable = conn.stableCount + stable;
6651 if (stable < 0) {
6652 throw new IllegalStateException("stableCount < 0: " + stable);
6653 }
6654
6655 if (unstable > 0) {
6656 conn.numUnstableIncs += unstable;
6657 }
6658 unstable = conn.unstableCount + unstable;
6659 if (unstable < 0) {
6660 throw new IllegalStateException("unstableCount < 0: " + unstable);
6661 }
6662
6663 if ((stable+unstable) <= 0) {
6664 throw new IllegalStateException("ref counts can't go to zero here: stable="
6665 + stable + " unstable=" + unstable);
6666 }
6667 conn.stableCount = stable;
6668 conn.unstableCount = unstable;
6669 return !conn.dead;
6670 }
6671 }
6672
6673 public void unstableProviderDied(IBinder connection) {
6674 ContentProviderConnection conn;
6675 try {
6676 conn = (ContentProviderConnection)connection;
6677 } catch (ClassCastException e) {
6678 String msg ="refContentProvider: " + connection
6679 + " not a ContentProviderConnection";
6680 Slog.w(TAG, msg);
6681 throw new IllegalArgumentException(msg);
6682 }
6683 if (conn == null) {
6684 throw new NullPointerException("connection is null");
6685 }
6686
6687 // Safely retrieve the content provider associated with the connection.
6688 IContentProvider provider;
6689 synchronized (this) {
6690 provider = conn.provider.provider;
6691 }
6692
6693 if (provider == null) {
6694 // Um, yeah, we're way ahead of you.
6695 return;
6696 }
6697
6698 // Make sure the caller is being honest with us.
6699 if (provider.asBinder().pingBinder()) {
6700 // Er, no, still looks good to us.
6701 synchronized (this) {
6702 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
6703 + " says " + conn + " died, but we don't agree");
6704 return;
6705 }
6706 }
6707
6708 // Well look at that! It's dead!
6709 synchronized (this) {
6710 if (conn.provider.provider != provider) {
6711 // But something changed... good enough.
6712 return;
6713 }
6714
6715 ProcessRecord proc = conn.provider.proc;
6716 if (proc == null || proc.thread == null) {
6717 // Seems like the process is already cleaned up.
6718 return;
6719 }
6720
6721 // As far as we're concerned, this is just like receiving a
6722 // death notification... just a bit prematurely.
6723 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
6724 + ") early provider death");
Dianne Hackbornbd145db2012-06-05 16:20:46 -07006725 final long ident = Binder.clearCallingIdentity();
6726 try {
6727 appDiedLocked(proc, proc.pid, proc.thread);
6728 } finally {
6729 Binder.restoreCallingIdentity(ident);
6730 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07006731 }
6732 }
6733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006734 public static final void installSystemProviders() {
Jeff Brown10e89712011-07-08 18:52:57 -07006735 List<ProviderInfo> providers;
Josh Bartel2ecce342010-02-25 10:55:48 -06006736 synchronized (mSelf) {
6737 ProcessRecord app = mSelf.mProcessNames.get("system", Process.SYSTEM_UID);
6738 providers = mSelf.generateApplicationProvidersLocked(app);
Dianne Hackborn5c83a5f2010-03-12 16:46:46 -08006739 if (providers != null) {
6740 for (int i=providers.size()-1; i>=0; i--) {
6741 ProviderInfo pi = (ProviderInfo)providers.get(i);
6742 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
6743 Slog.w(TAG, "Not installing system proc provider " + pi.name
6744 + ": not system .apk");
6745 providers.remove(i);
6746 }
Dianne Hackbornc3b91fd2010-02-23 17:25:30 -08006747 }
6748 }
6749 }
Josh Bartel2ecce342010-02-25 10:55:48 -06006750 if (providers != null) {
6751 mSystemThread.installSystemProviders(providers);
6752 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08006753
6754 mSelf.mCoreSettingsObserver = new CoreSettingsObserver(mSelf);
Mark Brophyc6350272011-08-05 16:16:39 +01006755
6756 mSelf.mUsageStatsService.monitorPackages();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006757 }
6758
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006759 /**
6760 * Allows app to retrieve the MIME type of a URI without having permission
6761 * to access its content provider.
6762 *
6763 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
6764 *
6765 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
6766 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
6767 */
6768 public String getProviderMimeType(Uri uri) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006769 enforceNotIsolatedCaller("getProviderMimeType");
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006770 final String name = uri.getAuthority();
Dianne Hackborn41203752012-08-31 14:05:51 -07006771 final int userId = UserHandle.getCallingUserId();
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006772 final long ident = Binder.clearCallingIdentity();
6773 ContentProviderHolder holder = null;
6774
6775 try {
Dianne Hackborn41203752012-08-31 14:05:51 -07006776 holder = getContentProviderExternalUnchecked(name, null, userId);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006777 if (holder != null) {
6778 return holder.provider.getType(uri);
6779 }
6780 } catch (RemoteException e) {
6781 Log.w(TAG, "Content provider dead retrieving " + uri, e);
6782 return null;
6783 } finally {
6784 if (holder != null) {
Dianne Hackborn41203752012-08-31 14:05:51 -07006785 removeContentProviderExternalUnchecked(name, null, userId);
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07006786 }
6787 Binder.restoreCallingIdentity(ident);
6788 }
6789
6790 return null;
6791 }
6792
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006793 // =========================================================
6794 // GLOBAL MANAGEMENT
6795 // =========================================================
6796
6797 final ProcessRecord newProcessRecordLocked(IApplicationThread thread,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006798 ApplicationInfo info, String customProcess, boolean isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006799 String proc = customProcess != null ? customProcess : info.processName;
6800 BatteryStatsImpl.Uid.Proc ps = null;
6801 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006802 int uid = info.uid;
6803 if (isolated) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07006804 int userId = UserHandle.getUserId(uid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006805 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
6806 uid = 0;
6807 while (true) {
6808 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
6809 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
6810 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
6811 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07006812 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006813 mNextIsolatedProcessUid++;
6814 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
6815 // No process for this uid, use it.
6816 break;
6817 }
6818 stepsLeft--;
6819 if (stepsLeft <= 0) {
6820 return null;
6821 }
6822 }
6823 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006824 synchronized (stats) {
6825 ps = stats.getProcessStatsLocked(info.uid, proc);
6826 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006827 return new ProcessRecord(ps, thread, info, proc, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006828 }
6829
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006830 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated) {
6831 ProcessRecord app;
6832 if (!isolated) {
6833 app = getProcessRecordLocked(info.processName, info.uid);
6834 } else {
6835 app = null;
6836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006837
6838 if (app == null) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08006839 app = newProcessRecordLocked(null, info, null, isolated);
6840 mProcessNames.put(info.processName, app.uid, app);
6841 if (isolated) {
6842 mIsolatedProcesses.put(app.uid, app);
6843 }
Dianne Hackborndd71fc82009-12-16 19:24:32 -08006844 updateLruProcessLocked(app, true, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006845 }
6846
Dianne Hackborne7f97212011-02-24 14:40:20 -08006847 // This package really, really can not be stopped.
6848 try {
6849 AppGlobals.getPackageManager().setPackageStoppedState(
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07006850 info.packageName, false, UserHandle.getUserId(app.uid));
Dianne Hackborne7f97212011-02-24 14:40:20 -08006851 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -08006852 } catch (IllegalArgumentException e) {
6853 Slog.w(TAG, "Failed trying to unstop package "
6854 + info.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -08006855 }
6856
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006857 if ((info.flags&(ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT))
6858 == (ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT)) {
6859 app.persistent = true;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07006860 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006861 }
6862 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
6863 mPersistentStartingProcesses.add(app);
6864 startProcessLocked(app, "added application", app.processName);
6865 }
6866
6867 return app;
6868 }
6869
6870 public void unhandledBack() {
6871 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
6872 "unhandledBack()");
6873
6874 synchronized(this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006875 int count = mMainStack.mHistory.size();
Joe Onorato8a9b2202010-02-26 18:56:32 -08006876 if (DEBUG_SWITCH) Slog.d(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006877 TAG, "Performing unhandledBack(): stack size = " + count);
6878 if (count > 1) {
6879 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006880 mMainStack.finishActivityLocked((ActivityRecord)mMainStack.mHistory.get(count-1),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006881 count-1, Activity.RESULT_CANCELED, null, "unhandled-back");
6882 Binder.restoreCallingIdentity(origId);
6883 }
6884 }
6885 }
6886
6887 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08006888 enforceNotIsolatedCaller("openContentUri");
Dianne Hackborn41203752012-08-31 14:05:51 -07006889 final int userId = UserHandle.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006890 String name = uri.getAuthority();
Dianne Hackborn41203752012-08-31 14:05:51 -07006891 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006892 ParcelFileDescriptor pfd = null;
6893 if (cph != null) {
6894 // We record the binder invoker's uid in thread-local storage before
6895 // going to the content provider to open the file. Later, in the code
6896 // that handles all permissions checks, we look for this uid and use
6897 // that rather than the Activity Manager's own uid. The effect is that
6898 // we do the check against the caller's permissions even though it looks
6899 // to the content provider like the Activity Manager itself is making
6900 // the request.
6901 sCallerIdentity.set(new Identity(
6902 Binder.getCallingPid(), Binder.getCallingUid()));
6903 try {
6904 pfd = cph.provider.openFile(uri, "r");
6905 } catch (FileNotFoundException e) {
6906 // do nothing; pfd will be returned null
6907 } finally {
6908 // Ensure that whatever happens, we clean up the identity state
6909 sCallerIdentity.remove();
6910 }
6911
6912 // We've got the fd now, so we're done with the provider.
Dianne Hackborn41203752012-08-31 14:05:51 -07006913 removeContentProviderExternalUnchecked(name, null, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006914 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006915 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006916 }
6917 return pfd;
6918 }
6919
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006920 // Actually is sleeping or shutting down or whatever else in the future
6921 // is an inactive state.
6922 public boolean isSleeping() {
6923 return mSleeping || mShuttingDown;
6924 }
6925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006926 public void goingToSleep() {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006927 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
6928 != PackageManager.PERMISSION_GRANTED) {
6929 throw new SecurityException("Requires permission "
6930 + android.Manifest.permission.DEVICE_POWER);
6931 }
6932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006933 synchronized(this) {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006934 mWentToSleep = true;
Jeff Brownc042ee22012-05-08 13:03:42 -07006935 updateEventDispatchingLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006936
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006937 if (!mSleeping) {
6938 mSleeping = true;
6939 mMainStack.stopIfSleepingLocked();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006940
Dianne Hackbornff5b1582012-04-12 17:24:07 -07006941 // Initialize the wake times of all processes.
6942 checkExcessivePowerUsageLocked(false);
6943 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6944 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6945 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6946 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006947 }
6948 }
6949
Dianne Hackborn55280a92009-05-07 15:53:46 -07006950 public boolean shutdown(int timeout) {
6951 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
6952 != PackageManager.PERMISSION_GRANTED) {
6953 throw new SecurityException("Requires permission "
6954 + android.Manifest.permission.SHUTDOWN);
6955 }
6956
6957 boolean timedout = false;
6958
6959 synchronized(this) {
6960 mShuttingDown = true;
Jeff Brownc042ee22012-05-08 13:03:42 -07006961 updateEventDispatchingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006962
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006963 if (mMainStack.mResumedActivity != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006964 mMainStack.stopIfSleepingLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -07006965 final long endTime = System.currentTimeMillis() + timeout;
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07006966 while (mMainStack.mResumedActivity != null
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08006967 || mMainStack.mPausingActivity != null) {
Dianne Hackborn55280a92009-05-07 15:53:46 -07006968 long delay = endTime - System.currentTimeMillis();
6969 if (delay <= 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08006970 Slog.w(TAG, "Activity manager shutdown timed out");
Dianne Hackborn55280a92009-05-07 15:53:46 -07006971 timedout = true;
6972 break;
6973 }
6974 try {
6975 this.wait();
6976 } catch (InterruptedException e) {
6977 }
6978 }
6979 }
6980 }
6981
6982 mUsageStatsService.shutdown();
6983 mBatteryStatsService.shutdown();
6984
6985 return timedout;
6986 }
6987
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006988 public final void activitySlept(IBinder token) {
6989 if (localLOGV) Slog.v(
6990 TAG, "Activity slept: token=" + token);
6991
6992 ActivityRecord r = null;
6993
6994 final long origId = Binder.clearCallingIdentity();
6995
6996 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07006997 r = mMainStack.isInStackLocked(token);
6998 if (r != null) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08006999 mMainStack.activitySleptLocked(r);
7000 }
7001 }
7002
7003 Binder.restoreCallingIdentity(origId);
7004 }
7005
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007006 private void comeOutOfSleepIfNeededLocked() {
7007 if (!mWentToSleep && !mLockScreenShown) {
7008 if (mSleeping) {
7009 mSleeping = false;
7010 mMainStack.awakeFromSleepingLocked();
7011 mMainStack.resumeTopActivityLocked(null);
7012 }
7013 }
7014 }
7015
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007016 public void wakingUp() {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007017 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7018 != PackageManager.PERMISSION_GRANTED) {
7019 throw new SecurityException("Requires permission "
7020 + android.Manifest.permission.DEVICE_POWER);
7021 }
7022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007023 synchronized(this) {
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007024 mWentToSleep = false;
Jeff Brownc042ee22012-05-08 13:03:42 -07007025 updateEventDispatchingLocked();
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007026 comeOutOfSleepIfNeededLocked();
7027 }
7028 }
7029
Jeff Brownc042ee22012-05-08 13:03:42 -07007030 private void updateEventDispatchingLocked() {
7031 mWindowManager.setEventDispatching(mBooted && !mWentToSleep && !mShuttingDown);
7032 }
7033
Dianne Hackbornff5b1582012-04-12 17:24:07 -07007034 public void setLockScreenShown(boolean shown) {
7035 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
7036 != PackageManager.PERMISSION_GRANTED) {
7037 throw new SecurityException("Requires permission "
7038 + android.Manifest.permission.DEVICE_POWER);
7039 }
7040
7041 synchronized(this) {
7042 mLockScreenShown = shown;
7043 comeOutOfSleepIfNeededLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007044 }
7045 }
7046
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007047 public void stopAppSwitches() {
7048 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7049 != PackageManager.PERMISSION_GRANTED) {
7050 throw new SecurityException("Requires permission "
7051 + android.Manifest.permission.STOP_APP_SWITCHES);
7052 }
7053
7054 synchronized(this) {
7055 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
7056 + APP_SWITCH_DELAY_TIME;
7057 mDidAppSwitch = false;
7058 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7059 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
7060 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
7061 }
7062 }
7063
7064 public void resumeAppSwitches() {
7065 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
7066 != PackageManager.PERMISSION_GRANTED) {
7067 throw new SecurityException("Requires permission "
7068 + android.Manifest.permission.STOP_APP_SWITCHES);
7069 }
7070
7071 synchronized(this) {
7072 // Note that we don't execute any pending app switches... we will
7073 // let those wait until either the timeout, or the next start
7074 // activity request.
7075 mAppSwitchesAllowedTime = 0;
7076 }
7077 }
7078
7079 boolean checkAppSwitchAllowedLocked(int callingPid, int callingUid,
7080 String name) {
7081 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
7082 return true;
7083 }
7084
7085 final int perm = checkComponentPermission(
7086 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -08007087 callingUid, -1, true);
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007088 if (perm == PackageManager.PERMISSION_GRANTED) {
7089 return true;
7090 }
7091
Joe Onorato8a9b2202010-02-26 18:56:32 -08007092 Slog.w(TAG, name + " request from " + callingUid + " stopped");
Dianne Hackborn95fc68f2009-05-19 18:37:45 -07007093 return false;
7094 }
7095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007096 public void setDebugApp(String packageName, boolean waitForDebugger,
7097 boolean persistent) {
7098 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
7099 "setDebugApp()");
7100
7101 // Note that this is not really thread safe if there are multiple
7102 // callers into it at the same time, but that's not a situation we
7103 // care about.
7104 if (persistent) {
7105 final ContentResolver resolver = mContext.getContentResolver();
7106 Settings.System.putString(
7107 resolver, Settings.System.DEBUG_APP,
7108 packageName);
7109 Settings.System.putInt(
7110 resolver, Settings.System.WAIT_FOR_DEBUGGER,
7111 waitForDebugger ? 1 : 0);
7112 }
7113
7114 synchronized (this) {
7115 if (!persistent) {
7116 mOrigDebugApp = mDebugApp;
7117 mOrigWaitForDebugger = mWaitForDebugger;
7118 }
7119 mDebugApp = packageName;
7120 mWaitForDebugger = waitForDebugger;
7121 mDebugTransient = !persistent;
7122 if (packageName != null) {
7123 final long origId = Binder.clearCallingIdentity();
Amith Yamasani483f3b02012-03-13 16:08:00 -07007124 forceStopPackageLocked(packageName, -1, false, false, true, true, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007125 Binder.restoreCallingIdentity(origId);
7126 }
7127 }
7128 }
7129
Siva Velusamy92a8b222012-03-09 16:24:04 -08007130 void setOpenGlTraceApp(ApplicationInfo app, String processName) {
7131 synchronized (this) {
7132 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7133 if (!isDebuggable) {
7134 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7135 throw new SecurityException("Process not debuggable: " + app.packageName);
7136 }
7137 }
7138
7139 mOpenGlTraceApp = processName;
7140 }
7141 }
7142
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07007143 void setProfileApp(ApplicationInfo app, String processName, String profileFile,
7144 ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
7145 synchronized (this) {
7146 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
7147 if (!isDebuggable) {
7148 if ((app.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
7149 throw new SecurityException("Process not debuggable: " + app.packageName);
7150 }
7151 }
7152 mProfileApp = processName;
7153 mProfileFile = profileFile;
7154 if (mProfileFd != null) {
7155 try {
7156 mProfileFd.close();
7157 } catch (IOException e) {
7158 }
7159 mProfileFd = null;
7160 }
7161 mProfileFd = profileFd;
7162 mProfileType = 0;
7163 mAutoStopProfiler = autoStopProfiler;
7164 }
7165 }
7166
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007167 public void setAlwaysFinish(boolean enabled) {
7168 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
7169 "setAlwaysFinish()");
7170
7171 Settings.System.putInt(
7172 mContext.getContentResolver(),
7173 Settings.System.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
7174
7175 synchronized (this) {
7176 mAlwaysFinishActivities = enabled;
7177 }
7178 }
7179
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007180 public void setActivityController(IActivityController controller) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007181 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007182 "setActivityController()");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007183 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07007184 mController = controller;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007185 }
7186 }
7187
Dianne Hackborn9327f4f2010-01-29 10:38:29 -08007188 public boolean isUserAMonkey() {
7189 // For now the fact that there is a controller implies
7190 // we have a monkey.
7191 synchronized (this) {
7192 return mController != null;
7193 }
7194 }
7195
Jeff Sharkeya4620792011-05-20 15:29:23 -07007196 public void registerProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007197 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
7198 "registerProcessObserver()");
7199 synchronized (this) {
7200 mProcessObservers.register(observer);
7201 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007202 }
7203
7204 public void unregisterProcessObserver(IProcessObserver observer) {
Dianne Hackborn21fbd1f2012-02-10 10:38:10 -08007205 synchronized (this) {
7206 mProcessObservers.unregister(observer);
7207 }
Jeff Sharkeya4620792011-05-20 15:29:23 -07007208 }
7209
Daniel Sandler69a48172010-06-23 16:29:36 -04007210 public void setImmersive(IBinder token, boolean immersive) {
7211 synchronized(this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007212 ActivityRecord r = mMainStack.isInStackLocked(token);
7213 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007214 throw new IllegalArgumentException();
7215 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007216 r.immersive = immersive;
7217 }
7218 }
7219
7220 public boolean isImmersive(IBinder token) {
7221 synchronized (this) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -07007222 ActivityRecord r = mMainStack.isInStackLocked(token);
7223 if (r == null) {
Daniel Sandler69a48172010-06-23 16:29:36 -04007224 throw new IllegalArgumentException();
7225 }
Daniel Sandler69a48172010-06-23 16:29:36 -04007226 return r.immersive;
7227 }
7228 }
7229
7230 public boolean isTopActivityImmersive() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08007231 enforceNotIsolatedCaller("startActivity");
Daniel Sandler69a48172010-06-23 16:29:36 -04007232 synchronized (this) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007233 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Daniel Sandler69a48172010-06-23 16:29:36 -04007234 return (r != null) ? r.immersive : false;
7235 }
7236 }
7237
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007238 public final void enterSafeMode() {
7239 synchronized(this) {
7240 // It only makes sense to do this before the system is ready
7241 // and started launching other packages.
7242 if (!mSystemReady) {
7243 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007244 AppGlobals.getPackageManager().enterSafeMode();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007245 } catch (RemoteException e) {
7246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007247 }
7248 }
7249 }
7250
Jeff Brownb09abc12011-01-13 21:08:27 -08007251 public final void showSafeModeOverlay() {
7252 View v = LayoutInflater.from(mContext).inflate(
7253 com.android.internal.R.layout.safe_mode, null);
7254 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
7255 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
7256 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
7257 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
Fabrice Di Meglioaac0d4e2012-07-19 19:21:26 -07007258 lp.gravity = Gravity.BOTTOM | Gravity.START;
Jeff Brownb09abc12011-01-13 21:08:27 -08007259 lp.format = v.getBackground().getOpacity();
7260 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
7261 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
7262 ((WindowManager)mContext.getSystemService(
7263 Context.WINDOW_SERVICE)).addView(v, lp);
7264 }
7265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007266 public void noteWakeupAlarm(IIntentSender sender) {
7267 if (!(sender instanceof PendingIntentRecord)) {
7268 return;
7269 }
7270 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
7271 synchronized (stats) {
7272 if (mBatteryStatsService.isOnBattery()) {
7273 mBatteryStatsService.enforceCallingPermission();
7274 PendingIntentRecord rec = (PendingIntentRecord)sender;
7275 int MY_UID = Binder.getCallingUid();
7276 int uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
7277 BatteryStatsImpl.Uid.Pkg pkg =
7278 stats.getPackageStatsLocked(uid, rec.key.packageName);
7279 pkg.incWakeupsLocked();
7280 }
7281 }
7282 }
7283
Dianne Hackborn64825172011-03-02 21:32:58 -08007284 public boolean killPids(int[] pids, String pReason, boolean secure) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007285 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007286 throw new SecurityException("killPids only available to the system");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007287 }
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007288 String reason = (pReason == null) ? "Unknown" : pReason;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007289 // XXX Note: don't acquire main activity lock here, because the window
7290 // manager calls in with its locks held.
7291
7292 boolean killed = false;
7293 synchronized (mPidsSelfLocked) {
7294 int[] types = new int[pids.length];
7295 int worstType = 0;
7296 for (int i=0; i<pids.length; i++) {
7297 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7298 if (proc != null) {
7299 int type = proc.setAdj;
7300 types[i] = type;
7301 if (type > worstType) {
7302 worstType = type;
7303 }
7304 }
7305 }
7306
Dianne Hackborn64825172011-03-02 21:32:58 -08007307 // If the worst oom_adj is somewhere in the hidden proc LRU range,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007308 // then constrain it so we will kill all hidden procs.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007309 if (worstType < ProcessList.HIDDEN_APP_MAX_ADJ
7310 && worstType > ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07007311 worstType = ProcessList.HIDDEN_APP_MIN_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007312 }
Dianne Hackborn64825172011-03-02 21:32:58 -08007313
7314 // If this is not a secure call, don't let it kill processes that
7315 // are important.
Dianne Hackborne02c88a2011-10-28 13:58:15 -07007316 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
7317 worstType = ProcessList.SERVICE_ADJ;
Dianne Hackborn64825172011-03-02 21:32:58 -08007318 }
7319
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007320 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007321 for (int i=0; i<pids.length; i++) {
7322 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
7323 if (proc == null) {
7324 continue;
7325 }
7326 int adj = proc.setAdj;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007327 if (adj >= worstType && !proc.killedBackground) {
Dianne Hackborn8633e682010-04-22 16:03:41 -07007328 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
Suchi Amalapurapue99bb5f2010-03-19 14:36:49 -07007329 EventLog.writeEvent(EventLogTags.AM_KILL, proc.pid,
7330 proc.processName, adj, reason);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007331 killed = true;
Dianne Hackborn906497c2010-05-10 15:57:38 -07007332 proc.killedBackground = true;
7333 Process.killProcessQuiet(pids[i]);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007334 }
7335 }
7336 }
7337 return killed;
7338 }
Jeff Sharkeyb9a07012012-03-22 17:00:04 -07007339
7340 @Override
7341 public boolean killProcessesBelowForeground(String reason) {
7342 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7343 throw new SecurityException("killProcessesBelowForeground() only available to system");
7344 }
7345
7346 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
7347 }
7348
7349 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
7350 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
7351 throw new SecurityException("killProcessesBelowAdj() only available to system");
7352 }
7353
7354 boolean killed = false;
7355 synchronized (mPidsSelfLocked) {
7356 final int size = mPidsSelfLocked.size();
7357 for (int i = 0; i < size; i++) {
7358 final int pid = mPidsSelfLocked.keyAt(i);
7359 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7360 if (proc == null) continue;
7361
7362 final int adj = proc.setAdj;
7363 if (adj > belowAdj && !proc.killedBackground) {
7364 Slog.w(TAG, "Killing " + proc + " (adj " + adj + "): " + reason);
7365 EventLog.writeEvent(
7366 EventLogTags.AM_KILL, proc.pid, proc.processName, adj, reason);
7367 killed = true;
7368 proc.killedBackground = true;
7369 Process.killProcessQuiet(pid);
7370 }
7371 }
7372 }
7373 return killed;
7374 }
7375
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007376 public final void startRunning(String pkg, String cls, String action,
7377 String data) {
7378 synchronized(this) {
7379 if (mStartRunning) {
7380 return;
7381 }
7382 mStartRunning = true;
7383 mTopComponent = pkg != null && cls != null
7384 ? new ComponentName(pkg, cls) : null;
7385 mTopAction = action != null ? action : Intent.ACTION_MAIN;
7386 mTopData = data;
7387 if (!mSystemReady) {
7388 return;
7389 }
7390 }
7391
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007392 systemReady(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007393 }
7394
7395 private void retrieveSettings() {
7396 final ContentResolver resolver = mContext.getContentResolver();
7397 String debugApp = Settings.System.getString(
7398 resolver, Settings.System.DEBUG_APP);
7399 boolean waitForDebugger = Settings.System.getInt(
7400 resolver, Settings.System.WAIT_FOR_DEBUGGER, 0) != 0;
7401 boolean alwaysFinishActivities = Settings.System.getInt(
7402 resolver, Settings.System.ALWAYS_FINISH_ACTIVITIES, 0) != 0;
7403
7404 Configuration configuration = new Configuration();
7405 Settings.System.getConfiguration(resolver, configuration);
7406
7407 synchronized (this) {
7408 mDebugApp = mOrigDebugApp = debugApp;
7409 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
7410 mAlwaysFinishActivities = alwaysFinishActivities;
7411 // This happens before any activities are started, so we can
7412 // change mConfiguration in-place.
Dianne Hackborn813075a62011-11-14 17:45:19 -08007413 updateConfigurationLocked(configuration, null, false, true);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007414 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007415 }
7416 }
7417
7418 public boolean testIsSystemReady() {
7419 // no need to synchronize(this) just to read & return the value
7420 return mSystemReady;
7421 }
7422
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007423 private static File getCalledPreBootReceiversFile() {
7424 File dataDir = Environment.getDataDirectory();
7425 File systemDir = new File(dataDir, "system");
7426 File fname = new File(systemDir, "called_pre_boots.dat");
7427 return fname;
7428 }
Dianne Hackborn661cd522011-08-22 00:26:20 -07007429
7430 static final int LAST_DONE_VERSION = 10000;
7431
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007432 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
7433 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
7434 File file = getCalledPreBootReceiversFile();
7435 FileInputStream fis = null;
7436 try {
7437 fis = new FileInputStream(file);
7438 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007439 int fvers = dis.readInt();
7440 if (fvers == LAST_DONE_VERSION) {
7441 String vers = dis.readUTF();
7442 String codename = dis.readUTF();
7443 String build = dis.readUTF();
7444 if (android.os.Build.VERSION.RELEASE.equals(vers)
7445 && android.os.Build.VERSION.CODENAME.equals(codename)
7446 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
7447 int num = dis.readInt();
7448 while (num > 0) {
7449 num--;
7450 String pkg = dis.readUTF();
7451 String cls = dis.readUTF();
7452 lastDoneReceivers.add(new ComponentName(pkg, cls));
7453 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007454 }
7455 }
7456 } catch (FileNotFoundException e) {
7457 } catch (IOException e) {
7458 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
7459 } finally {
7460 if (fis != null) {
7461 try {
7462 fis.close();
7463 } catch (IOException e) {
7464 }
7465 }
7466 }
7467 return lastDoneReceivers;
7468 }
7469
7470 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
7471 File file = getCalledPreBootReceiversFile();
7472 FileOutputStream fos = null;
7473 DataOutputStream dos = null;
7474 try {
7475 Slog.i(TAG, "Writing new set of last done pre-boot receivers...");
7476 fos = new FileOutputStream(file);
7477 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
Dianne Hackborn661cd522011-08-22 00:26:20 -07007478 dos.writeInt(LAST_DONE_VERSION);
7479 dos.writeUTF(android.os.Build.VERSION.RELEASE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007480 dos.writeUTF(android.os.Build.VERSION.CODENAME);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007481 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007482 dos.writeInt(list.size());
7483 for (int i=0; i<list.size(); i++) {
7484 dos.writeUTF(list.get(i).getPackageName());
7485 dos.writeUTF(list.get(i).getClassName());
7486 }
7487 } catch (IOException e) {
7488 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
7489 file.delete();
7490 } finally {
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07007491 FileUtils.sync(fos);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007492 if (dos != null) {
7493 try {
7494 dos.close();
7495 } catch (IOException e) {
7496 // TODO Auto-generated catch block
7497 e.printStackTrace();
7498 }
7499 }
7500 }
7501 }
7502
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007503 public void systemReady(final Runnable goingCallback) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007504 synchronized(this) {
7505 if (mSystemReady) {
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007506 if (goingCallback != null) goingCallback.run();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007507 return;
7508 }
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007509
7510 // Check to see if there are any update receivers to run.
7511 if (!mDidUpdate) {
7512 if (mWaitingUpdate) {
7513 return;
7514 }
7515 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
7516 List<ResolveInfo> ris = null;
7517 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007518 ris = AppGlobals.getPackageManager().queryIntentReceivers(
Amith Yamasani483f3b02012-03-13 16:08:00 -07007519 intent, null, 0, 0);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007520 } catch (RemoteException e) {
7521 }
7522 if (ris != null) {
7523 for (int i=ris.size()-1; i>=0; i--) {
7524 if ((ris.get(i).activityInfo.applicationInfo.flags
7525 &ApplicationInfo.FLAG_SYSTEM) == 0) {
7526 ris.remove(i);
7527 }
7528 }
7529 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007530
7531 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
7532
7533 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007534 for (int i=0; i<ris.size(); i++) {
7535 ActivityInfo ai = ris.get(i).activityInfo;
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007536 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7537 if (lastDoneReceivers.contains(comp)) {
7538 ris.remove(i);
7539 i--;
7540 }
7541 }
Dianne Hackborn29aae6f2011-08-18 18:30:09 -07007542
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007543 for (int i=0; i<ris.size(); i++) {
7544 ActivityInfo ai = ris.get(i).activityInfo;
7545 ComponentName comp = new ComponentName(ai.packageName, ai.name);
7546 doneReceivers.add(comp);
7547 intent.setComponent(comp);
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007548 IIntentReceiver finisher = null;
Dianne Hackbornd6847842010-01-12 18:14:19 -08007549 if (i == ris.size()-1) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007550 finisher = new IIntentReceiver.Stub() {
7551 public void performReceive(Intent intent, int resultCode,
Dianne Hackborn68d881c2009-10-05 13:58:17 -07007552 String data, Bundle extras, boolean ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -07007553 boolean sticky, int sendingUser) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007554 // The raw IIntentReceiver interface is called
7555 // with the AM lock held, so redispatch to
7556 // execute our code without the lock.
7557 mHandler.post(new Runnable() {
7558 public void run() {
7559 synchronized (ActivityManagerService.this) {
7560 mDidUpdate = true;
7561 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007562 writeLastDonePreBootReceivers(doneReceivers);
Dianne Hackborn661cd522011-08-22 00:26:20 -07007563 showBootMessage(mContext.getText(
7564 R.string.android_upgrading_complete),
7565 false);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07007566 systemReady(goingCallback);
7567 }
7568 });
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007569 }
7570 };
7571 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08007572 Slog.i(TAG, "Sending system update to: " + intent.getComponent());
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07007573 // XXX also need to send this to stopped users(!!!)
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007574 broadcastIntentLocked(null, null, intent, null, finisher,
Amith Yamasani742a6712011-05-04 14:49:28 -07007575 0, null, null, null, true, false, MY_PID, Process.SYSTEM_UID,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07007576 UserHandle.USER_ALL);
Dianne Hackbornd6847842010-01-12 18:14:19 -08007577 if (finisher != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007578 mWaitingUpdate = true;
7579 }
7580 }
7581 }
7582 if (mWaitingUpdate) {
7583 return;
7584 }
7585 mDidUpdate = true;
7586 }
7587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007588 mSystemReady = true;
7589 if (!mStartRunning) {
7590 return;
7591 }
7592 }
7593
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007594 ArrayList<ProcessRecord> procsToKill = null;
7595 synchronized(mPidsSelfLocked) {
7596 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
7597 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
7598 if (!isAllowedWhileBooting(proc.info)){
7599 if (procsToKill == null) {
7600 procsToKill = new ArrayList<ProcessRecord>();
7601 }
7602 procsToKill.add(proc);
7603 }
7604 }
7605 }
7606
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007607 synchronized(this) {
7608 if (procsToKill != null) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007609 for (int i=procsToKill.size()-1; i>=0; i--) {
7610 ProcessRecord proc = procsToKill.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -08007611 Slog.i(TAG, "Removing system update proc: " + proc);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007612 removeProcessLocked(proc, true, false, "system update done");
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007613 }
7614 }
Dianne Hackborncef65ee2010-09-30 18:27:22 -07007615
7616 // Now that we have cleaned up any update processes, we
7617 // are ready to start launching real processes and know that
7618 // we won't trample on them any more.
7619 mProcessesReady = true;
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007620 }
7621
Joe Onorato8a9b2202010-02-26 18:56:32 -08007622 Slog.i(TAG, "System now ready");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007623 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007624 SystemClock.uptimeMillis());
7625
7626 synchronized(this) {
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007627 // Make sure we have no pre-ready processes sitting around.
7628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007629 if (mFactoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL) {
7630 ResolveInfo ri = mContext.getPackageManager()
7631 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
Dianne Hackborn1655be42009-05-08 14:29:01 -07007632 STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007633 CharSequence errorMsg = null;
7634 if (ri != null) {
7635 ActivityInfo ai = ri.activityInfo;
7636 ApplicationInfo app = ai.applicationInfo;
7637 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
7638 mTopAction = Intent.ACTION_FACTORY_TEST;
7639 mTopData = null;
7640 mTopComponent = new ComponentName(app.packageName,
7641 ai.name);
7642 } else {
7643 errorMsg = mContext.getResources().getText(
7644 com.android.internal.R.string.factorytest_not_system);
7645 }
7646 } else {
7647 errorMsg = mContext.getResources().getText(
7648 com.android.internal.R.string.factorytest_no_action);
7649 }
7650 if (errorMsg != null) {
7651 mTopAction = null;
7652 mTopData = null;
7653 mTopComponent = null;
7654 Message msg = Message.obtain();
7655 msg.what = SHOW_FACTORY_ERROR_MSG;
7656 msg.getData().putCharSequence("msg", errorMsg);
7657 mHandler.sendMessage(msg);
7658 }
7659 }
7660 }
7661
7662 retrieveSettings();
7663
Dianne Hackborna34f1ad2009-09-02 13:26:28 -07007664 if (goingCallback != null) goingCallback.run();
7665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007666 synchronized (this) {
7667 if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
7668 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007669 List apps = AppGlobals.getPackageManager().
Dianne Hackborn1655be42009-05-08 14:29:01 -07007670 getPersistentApplications(STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007671 if (apps != null) {
7672 int N = apps.size();
7673 int i;
7674 for (i=0; i<N; i++) {
7675 ApplicationInfo info
7676 = (ApplicationInfo)apps.get(i);
7677 if (info != null &&
7678 !info.packageName.equals("android")) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007679 addAppLocked(info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007680 }
7681 }
7682 }
7683 } catch (RemoteException ex) {
7684 // pm is in same process, this will never happen.
7685 }
7686 }
7687
Dianne Hackborn9acc0302009-08-25 00:27:12 -07007688 // Start up initial activity.
7689 mBooting = true;
7690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007691 try {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07007692 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007693 Message msg = Message.obtain();
7694 msg.what = SHOW_UID_ERROR_MSG;
7695 mHandler.sendMessage(msg);
7696 }
7697 } catch (RemoteException e) {
7698 }
7699
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007700 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007701 }
7702 }
7703
Dan Egnorb7f03672009-12-09 16:22:32 -08007704 private boolean makeAppCrashingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007705 String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007706 app.crashing = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007707 app.crashingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007708 ActivityManager.ProcessErrorStateInfo.CRASHED, null, shortMsg, longMsg, stackTrace);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007709 startAppProblemLocked(app);
7710 app.stopFreezingAllLocked();
7711 return handleAppCrashLocked(app);
7712 }
7713
Dan Egnorb7f03672009-12-09 16:22:32 -08007714 private void makeAppNotRespondingLocked(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007715 String activity, String shortMsg, String longMsg) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007716 app.notResponding = true;
Dan Egnorb7f03672009-12-09 16:22:32 -08007717 app.notRespondingReport = generateProcessError(app,
Dan Egnor60d87622009-12-16 16:32:58 -08007718 ActivityManager.ProcessErrorStateInfo.NOT_RESPONDING,
7719 activity, shortMsg, longMsg, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 startAppProblemLocked(app);
7721 app.stopFreezingAllLocked();
7722 }
7723
7724 /**
7725 * Generate a process error record, suitable for attachment to a ProcessRecord.
7726 *
7727 * @param app The ProcessRecord in which the error occurred.
7728 * @param condition Crashing, Application Not Responding, etc. Values are defined in
7729 * ActivityManager.AppErrorStateInfo
Dan Egnor60d87622009-12-16 16:32:58 -08007730 * @param activity The activity associated with the crash, if known.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007731 * @param shortMsg Short message describing the crash.
7732 * @param longMsg Long message describing the crash.
Dan Egnorb7f03672009-12-09 16:22:32 -08007733 * @param stackTrace Full crash stack trace, may be null.
7734 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007735 * @return Returns a fully-formed AppErrorStateInfo record.
7736 */
7737 private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
Dan Egnor60d87622009-12-16 16:32:58 -08007738 int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007739 ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
Dan Egnorb7f03672009-12-09 16:22:32 -08007740
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007741 report.condition = condition;
7742 report.processName = app.processName;
7743 report.pid = app.pid;
7744 report.uid = app.info.uid;
Dan Egnor60d87622009-12-16 16:32:58 -08007745 report.tag = activity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007746 report.shortMsg = shortMsg;
7747 report.longMsg = longMsg;
Dan Egnorb7f03672009-12-09 16:22:32 -08007748 report.stackTrace = stackTrace;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007749
7750 return report;
7751 }
7752
Dan Egnor42471dd2010-01-07 17:25:22 -08007753 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007754 synchronized (this) {
7755 app.crashing = false;
7756 app.crashingReport = null;
7757 app.notResponding = false;
7758 app.notRespondingReport = null;
7759 if (app.anrDialog == fromDialog) {
7760 app.anrDialog = null;
7761 }
7762 if (app.waitDialog == fromDialog) {
7763 app.waitDialog = null;
7764 }
7765 if (app.pid > 0 && app.pid != MY_PID) {
Dan Egnor42471dd2010-01-07 17:25:22 -08007766 handleAppCrashLocked(app);
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007767 Slog.i(ActivityManagerService.TAG, "Killing " + app + ": user's request");
Dianne Hackborn8633e682010-04-22 16:03:41 -07007768 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
7769 app.processName, app.setAdj, "user's request after error");
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07007770 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007771 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772 }
7773 }
Dan Egnor42471dd2010-01-07 17:25:22 -08007774
Dan Egnorb7f03672009-12-09 16:22:32 -08007775 private boolean handleAppCrashLocked(ProcessRecord app) {
Mike Lockwood86548c42011-09-13 17:21:46 -04007776 if (mHeadless) {
7777 Log.e(TAG, "handleAppCrashLocked: " + app.processName);
7778 return false;
7779 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007780 long now = SystemClock.uptimeMillis();
7781
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007782 Long crashTime;
7783 if (!app.isolated) {
7784 crashTime = mProcessCrashTimes.get(app.info.processName, app.uid);
7785 } else {
7786 crashTime = null;
7787 }
Dianne Hackborn7d608422011-08-07 16:24:18 -07007788 if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007789 // This process loses!
Joe Onorato8a9b2202010-02-26 18:56:32 -08007790 Slog.w(TAG, "Process " + app.info.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007791 + " has crashed too many times: killing!");
Doug Zongker2bec3d42009-12-04 12:52:44 -08007792 EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007793 app.info.processName, app.uid);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007794 for (int i=mMainStack.mHistory.size()-1; i>=0; i--) {
7795 ActivityRecord r = (ActivityRecord)mMainStack.mHistory.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007796 if (r.app == app) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08007797 Slog.w(TAG, " Force finishing activity "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007798 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007799 r.stack.finishActivityLocked(r, i, Activity.RESULT_CANCELED, null, "crashed");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007800 }
7801 }
7802 if (!app.persistent) {
7803 // We don't want to start this process again until the user
7804 // explicitly does so... but for persistent process, we really
7805 // need to keep it running. If a persistent process is actually
7806 // repeatedly crashing, then badness for everyone.
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007807 EventLog.writeEvent(EventLogTags.AM_PROC_BAD, app.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007808 app.info.processName);
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007809 if (!app.isolated) {
7810 // XXX We don't have a way to mark isolated processes
7811 // as bad, since they don't have a peristent identity.
7812 mBadProcesses.put(app.info.processName, app.uid, now);
7813 mProcessCrashTimes.remove(app.info.processName, app.uid);
7814 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007815 app.bad = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007816 app.removed = true;
Dianne Hackborn130b0d22011-07-26 22:07:48 -07007817 // Don't let services in this process be restarted and potentially
7818 // annoy the user repeatedly. Unless it is persistent, since those
7819 // processes run critical code.
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -08007820 removeProcessLocked(app, false, false, "crash");
Dianne Hackborncb44d962011-03-10 17:02:27 -08007821 mMainStack.resumeTopActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007822 return false;
7823 }
Dianne Hackborncb44d962011-03-10 17:02:27 -08007824 mMainStack.resumeTopActivityLocked(null);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007825 } else {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007826 ActivityRecord r = mMainStack.topRunningActivityLocked(null);
Kevin Hester-Chowd87a9be2012-03-05 08:01:00 -08007827 if (r != null && r.app == app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007828 // If the top running activity is from this crashing
7829 // process, then terminate it to avoid getting in a loop.
7830 Slog.w(TAG, " Force finishing activity "
7831 + r.intent.getComponent().flattenToShortString());
Dianne Hackbornbe707852011-11-11 14:32:10 -08007832 int index = mMainStack.indexOfActivityLocked(r);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007833 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007834 Activity.RESULT_CANCELED, null, "crashed");
Dianne Hackborn070783f2010-12-29 16:46:28 -08007835 // Also terminate any activities below it that aren't yet
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007836 // stopped, to avoid a situation where one will get
7837 // re-start our crashing activity once it gets resumed again.
7838 index--;
7839 if (index >= 0) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007840 r = (ActivityRecord)mMainStack.mHistory.get(index);
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007841 if (r.state == ActivityState.RESUMED
7842 || r.state == ActivityState.PAUSING
7843 || r.state == ActivityState.PAUSED) {
Dianne Hackborn94cb2eb2011-01-13 21:09:44 -08007844 if (!r.isHomeActivity || mHomeProcess != r.app) {
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007845 Slog.w(TAG, " Force finishing activity "
7846 + r.intent.getComponent().flattenToShortString());
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07007847 r.stack.finishActivityLocked(r, index,
Dianne Hackbornf83c5552010-03-31 22:19:32 -07007848 Activity.RESULT_CANCELED, null, "crashed");
7849 }
7850 }
7851 }
7852 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007853 }
7854
7855 // Bump up the crash count of any services currently running in the proc.
7856 if (app.services.size() != 0) {
7857 // Any services running in the application need to be placed
7858 // back in the pending list.
Dianne Hackborn860755f2010-06-03 18:47:52 -07007859 Iterator<ServiceRecord> it = app.services.iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007860 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -07007861 ServiceRecord sr = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007862 sr.crashCount++;
7863 }
7864 }
Mattias Larssona4fd0072010-06-22 22:37:03 +02007865
7866 // If the crashing process is what we consider to be the "home process" and it has been
7867 // replaced by a third-party app, clear the package preferred activities from packages
7868 // with a home activity running in the process to prevent a repeatedly crashing app
7869 // from blocking the user to manually clear the list.
7870 if (app == mHomeProcess && mHomeProcess.activities.size() > 0
7871 && (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
7872 Iterator it = mHomeProcess.activities.iterator();
7873 while (it.hasNext()) {
Jean-Baptiste Queru5ea89f72010-07-30 09:30:31 -07007874 ActivityRecord r = (ActivityRecord)it.next();
Mattias Larssona4fd0072010-06-22 22:37:03 +02007875 if (r.isHomeActivity) {
7876 Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
7877 try {
7878 ActivityThread.getPackageManager()
7879 .clearPackagePreferredActivities(r.packageName);
7880 } catch (RemoteException c) {
7881 // pm is in same process, this will never happen.
7882 }
7883 }
7884 }
7885 }
7886
Dianne Hackborna0c283e2012-02-09 10:47:01 -08007887 if (!app.isolated) {
7888 // XXX Can't keep track of crash times for isolated processes,
7889 // because they don't have a perisistent identity.
7890 mProcessCrashTimes.put(app.info.processName, app.uid, now);
7891 }
7892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007893 return true;
7894 }
7895
7896 void startAppProblemLocked(ProcessRecord app) {
Dianne Hackborn21f1bd12010-02-19 17:02:21 -08007897 app.errorReportReceiver = ApplicationErrorReport.getErrorReportReceiver(
7898 mContext, app.info.packageName, app.info.flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007899 skipCurrentReceiverLocked(app);
7900 }
7901
7902 void skipCurrentReceiverLocked(ProcessRecord app) {
Christopher Tatef46723b2012-01-26 14:19:24 -08007903 for (BroadcastQueue queue : mBroadcastQueues) {
7904 queue.skipCurrentReceiverLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905 }
7906 }
7907
Dan Egnor60d87622009-12-16 16:32:58 -08007908 /**
7909 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
7910 * The application process will exit immediately after this call returns.
7911 * @param app object of the crashing app, null for the system server
7912 * @param crashInfo describing the exception
7913 */
7914 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007915 ProcessRecord r = findAppProcess(app, "Crash");
Jeff Sharkeya353d262011-10-28 11:12:06 -07007916 final String processName = app == null ? "system_server"
7917 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08007918
7919 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07007920 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08007921 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08007922 crashInfo.exceptionClassName,
7923 crashInfo.exceptionMessage,
7924 crashInfo.throwFileName,
7925 crashInfo.throwLineNumber);
7926
Jeff Sharkeya353d262011-10-28 11:12:06 -07007927 addErrorToDropBox("crash", r, processName, null, null, null, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08007928
7929 crashApplication(r, crashInfo);
7930 }
7931
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007932 public void handleApplicationStrictModeViolation(
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007933 IBinder app,
7934 int violationMask,
7935 StrictMode.ViolationInfo info) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08007936 ProcessRecord r = findAppProcess(app, "StrictMode");
7937 if (r == null) {
7938 return;
7939 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007940
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007941 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
Brad Fitzpatrickf3d86be2010-11-23 10:31:52 -08007942 Integer stackFingerprint = info.hashCode();
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007943 boolean logIt = true;
7944 synchronized (mAlreadyLoggedViolatedStacks) {
7945 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
7946 logIt = false;
7947 // TODO: sub-sample into EventLog for these, with
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007948 // the info.durationMillis? Then we'd get
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007949 // the relative pain numbers, without logging all
7950 // the stack traces repeatedly. We'd want to do
7951 // likewise in the client code, which also does
7952 // dup suppression, before the Binder call.
7953 } else {
7954 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
7955 mAlreadyLoggedViolatedStacks.clear();
7956 }
7957 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
7958 }
7959 }
7960 if (logIt) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007961 logStrictModeViolationToDropBox(r, info);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007962 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007963 }
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007964
7965 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
7966 AppErrorResult result = new AppErrorResult();
7967 synchronized (this) {
7968 final long origId = Binder.clearCallingIdentity();
7969
7970 Message msg = Message.obtain();
7971 msg.what = SHOW_STRICT_MODE_VIOLATION_MSG;
7972 HashMap<String, Object> data = new HashMap<String, Object>();
7973 data.put("result", result);
7974 data.put("app", r);
Brad Fitzpatrick143666f2010-06-14 12:40:21 -07007975 data.put("violationMask", violationMask);
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007976 data.put("info", info);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007977 msg.obj = data;
7978 mHandler.sendMessage(msg);
7979
7980 Binder.restoreCallingIdentity(origId);
7981 }
7982 int res = result.get();
Dianne Hackbornb424b632010-08-18 15:59:05 -07007983 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
Brad Fitzpatrick46d42382010-06-11 13:57:58 -07007984 }
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07007985 }
7986
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007987 // Depending on the policy in effect, there could be a bunch of
7988 // these in quick succession so we try to batch these together to
7989 // minimize disk writes, number of dropbox entries, and maximize
7990 // compression, by having more fewer, larger records.
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07007991 private void logStrictModeViolationToDropBox(
7992 ProcessRecord process,
7993 StrictMode.ViolationInfo info) {
7994 if (info == null) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07007995 return;
7996 }
7997 final boolean isSystemApp = process == null ||
7998 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
7999 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008000 final String processName = process == null ? "unknown" : process.processName;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008001 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
8002 final DropBoxManager dbox = (DropBoxManager)
8003 mContext.getSystemService(Context.DROPBOX_SERVICE);
8004
8005 // Exit early if the dropbox isn't configured to accept this report type.
8006 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8007
8008 boolean bufferWasEmpty;
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008009 boolean needsFlush;
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008010 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
8011 synchronized (sb) {
8012 bufferWasEmpty = sb.length() == 0;
Jeff Sharkeya353d262011-10-28 11:12:06 -07008013 appendDropBoxProcessHeaders(process, processName, sb);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008014 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
8015 sb.append("System-App: ").append(isSystemApp).append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008016 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
8017 if (info.violationNumThisLoop != 0) {
8018 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
8019 }
Brad Fitzpatrick599ca292010-10-22 14:47:03 -07008020 if (info.numAnimationsRunning != 0) {
8021 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
8022 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07008023 if (info.broadcastIntentAction != null) {
8024 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
8025 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008026 if (info.durationMillis != -1) {
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008027 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008028 }
Brad Fitzpatrickbfbe5772011-01-19 00:10:58 -08008029 if (info.numInstances != -1) {
8030 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
8031 }
Brad Fitzpatricke7520d82010-11-10 18:08:36 -08008032 if (info.tags != null) {
8033 for (String tag : info.tags) {
8034 sb.append("Span-Tag: ").append(tag).append("\n");
8035 }
8036 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008037 sb.append("\n");
Brad Fitzpatrickcb9ceb12010-07-29 14:29:02 -07008038 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
8039 sb.append(info.crashInfo.stackTrace);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008040 }
8041 sb.append("\n");
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008042
8043 // Only buffer up to ~64k. Various logging bits truncate
8044 // things at 128k.
8045 needsFlush = (sb.length() > 64 * 1024);
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008046 }
8047
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008048 // Flush immediately if the buffer's grown too large, or this
8049 // is a non-system app. Non-system apps are isolated with a
8050 // different tag & policy and not batched.
8051 //
8052 // Batching is useful during internal testing with
8053 // StrictMode settings turned up high. Without batching,
8054 // thousands of separate files could be created on boot.
8055 if (!isSystemApp || needsFlush) {
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008056 new Thread("Error dump: " + dropboxTag) {
8057 @Override
8058 public void run() {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008059 String report;
8060 synchronized (sb) {
8061 report = sb.toString();
8062 sb.delete(0, sb.length());
8063 sb.trimToSize();
8064 }
8065 if (report.length() != 0) {
8066 dbox.addText(dropboxTag, report);
8067 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008068 }
8069 }.start();
8070 return;
8071 }
8072
8073 // System app batching:
8074 if (!bufferWasEmpty) {
Brad Fitzpatricke73eb532010-07-27 16:54:39 -07008075 // An existing dropbox-writing thread is outstanding, so
8076 // we don't need to start it up. The existing thread will
8077 // catch the buffer appends we just did.
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008078 return;
8079 }
8080
8081 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
8082 // (After this point, we shouldn't access AMS internal data structures.)
8083 new Thread("Error dump: " + dropboxTag) {
8084 @Override
8085 public void run() {
8086 // 5 second sleep to let stacks arrive and be batched together
8087 try {
8088 Thread.sleep(5000); // 5 seconds
8089 } catch (InterruptedException e) {}
8090
8091 String errorReport;
8092 synchronized (mStrictModeBuffer) {
8093 errorReport = mStrictModeBuffer.toString();
8094 if (errorReport.length() == 0) {
8095 return;
8096 }
8097 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
8098 mStrictModeBuffer.trimToSize();
8099 }
8100 dbox.addText(dropboxTag, errorReport);
8101 }
8102 }.start();
8103 }
8104
Dan Egnor60d87622009-12-16 16:32:58 -08008105 /**
8106 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
8107 * @param app object of the crashing app, null for the system server
8108 * @param tag reported by the caller
8109 * @param crashInfo describing the context of the error
8110 * @return true if the process should exit immediately (WTF is fatal)
8111 */
8112 public boolean handleApplicationWtf(IBinder app, String tag,
Dan Egnorb7f03672009-12-09 16:22:32 -08008113 ApplicationErrorReport.CrashInfo crashInfo) {
Dianne Hackborncb44d962011-03-10 17:02:27 -08008114 ProcessRecord r = findAppProcess(app, "WTF");
Jeff Sharkeya353d262011-10-28 11:12:06 -07008115 final String processName = app == null ? "system_server"
8116 : (r == null ? "unknown" : r.processName);
Dan Egnor60d87622009-12-16 16:32:58 -08008117
8118 EventLog.writeEvent(EventLogTags.AM_WTF, Binder.getCallingPid(),
Jeff Sharkeya353d262011-10-28 11:12:06 -07008119 processName,
Dan Egnor2780e732010-01-22 14:47:35 -08008120 r == null ? -1 : r.info.flags,
Dan Egnor60d87622009-12-16 16:32:58 -08008121 tag, crashInfo.exceptionMessage);
8122
Jeff Sharkeya353d262011-10-28 11:12:06 -07008123 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
Dan Egnor60d87622009-12-16 16:32:58 -08008124
Dianne Hackborn1ab43772011-03-15 14:38:02 -07008125 if (r != null && r.pid != Process.myPid() &&
8126 Settings.Secure.getInt(mContext.getContentResolver(),
8127 Settings.Secure.WTF_IS_FATAL, 0) != 0) {
Dan Egnor60d87622009-12-16 16:32:58 -08008128 crashApplication(r, crashInfo);
8129 return true;
8130 } else {
8131 return false;
8132 }
8133 }
8134
8135 /**
8136 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
8137 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
8138 */
Dianne Hackborncb44d962011-03-10 17:02:27 -08008139 private ProcessRecord findAppProcess(IBinder app, String reason) {
Dan Egnor60d87622009-12-16 16:32:58 -08008140 if (app == null) {
8141 return null;
8142 }
8143
8144 synchronized (this) {
8145 for (SparseArray<ProcessRecord> apps : mProcessNames.getMap().values()) {
8146 final int NA = apps.size();
8147 for (int ia=0; ia<NA; ia++) {
8148 ProcessRecord p = apps.valueAt(ia);
8149 if (p.thread != null && p.thread.asBinder() == app) {
8150 return p;
8151 }
8152 }
8153 }
8154
Dianne Hackborncb44d962011-03-10 17:02:27 -08008155 Slog.w(TAG, "Can't find mystery application for " + reason
8156 + " from pid=" + Binder.getCallingPid()
8157 + " uid=" + Binder.getCallingUid() + ": " + app);
Dan Egnor60d87622009-12-16 16:32:58 -08008158 return null;
8159 }
8160 }
8161
8162 /**
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008163 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
8164 * to append various headers to the dropbox log text.
Dan Egnor60d87622009-12-16 16:32:58 -08008165 */
Jeff Sharkeya353d262011-10-28 11:12:06 -07008166 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
8167 StringBuilder sb) {
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008168 // Watchdog thread ends up invoking this function (with
8169 // a null ProcessRecord) to add the stack file to dropbox.
8170 // Do not acquire a lock on this (am) in such cases, as it
8171 // could cause a potential deadlock, if and when watchdog
8172 // is invoked due to unavailability of lock on am and it
8173 // would prevent watchdog from killing system_server.
8174 if (process == null) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008175 sb.append("Process: ").append(processName).append("\n");
Vairavan Srinivasan68a4e0a2011-02-14 20:45:59 -08008176 return;
8177 }
Brad Fitzpatrick1e02d362010-09-10 09:19:50 -07008178 // Note: ProcessRecord 'process' is guarded by the service
8179 // instance. (notably process.pkgList, which could otherwise change
8180 // concurrently during execution of this method)
8181 synchronized (this) {
Jeff Sharkeya353d262011-10-28 11:12:06 -07008182 sb.append("Process: ").append(processName).append("\n");
Dan Egnora455d192010-03-12 08:52:28 -08008183 int flags = process.info.flags;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008184 IPackageManager pm = AppGlobals.getPackageManager();
Dan Egnora455d192010-03-12 08:52:28 -08008185 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
8186 for (String pkg : process.pkgList) {
8187 sb.append("Package: ").append(pkg);
Dan Egnor42471dd2010-01-07 17:25:22 -08008188 try {
Amith Yamasanif203aee2012-08-29 18:41:53 -07008189 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
Dan Egnora455d192010-03-12 08:52:28 -08008190 if (pi != null) {
8191 sb.append(" v").append(pi.versionCode);
8192 if (pi.versionName != null) {
8193 sb.append(" (").append(pi.versionName).append(")");
8194 }
8195 }
8196 } catch (RemoteException e) {
8197 Slog.e(TAG, "Error getting package info: " + pkg, e);
Dan Egnor60d87622009-12-16 16:32:58 -08008198 }
Dan Egnora455d192010-03-12 08:52:28 -08008199 sb.append("\n");
Dan Egnor60d87622009-12-16 16:32:58 -08008200 }
Dan Egnora455d192010-03-12 08:52:28 -08008201 }
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008202 }
8203
8204 private static String processClass(ProcessRecord process) {
8205 if (process == null || process.pid == MY_PID) {
8206 return "system_server";
8207 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
8208 return "system_app";
8209 } else {
8210 return "data_app";
8211 }
8212 }
8213
8214 /**
8215 * Write a description of an error (crash, WTF, ANR) to the drop box.
8216 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
8217 * @param process which caused the error, null means the system server
8218 * @param activity which triggered the error, null if unknown
8219 * @param parent activity related to the error, null if unknown
8220 * @param subject line related to the error, null if absent
8221 * @param report in long form describing the error, null if absent
8222 * @param logFile to include in the report, null if none
8223 * @param crashInfo giving an application stack trace, null if absent
8224 */
8225 public void addErrorToDropBox(String eventType,
Jeff Sharkeya353d262011-10-28 11:12:06 -07008226 ProcessRecord process, String processName, ActivityRecord activity,
8227 ActivityRecord parent, String subject,
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07008228 final String report, final File logFile,
8229 final ApplicationErrorReport.CrashInfo crashInfo) {
8230 // NOTE -- this must never acquire the ActivityManagerService lock,
8231 // otherwise the watchdog may be prevented from resetting the system.
8232
8233 final String dropboxTag = processClass(process) + "_" + eventType;
8234 final DropBoxManager dbox = (DropBoxManager)
8235 mContext.getSystemService(Context.DROPBOX_SERVICE);
8236
8237 // Exit early if the dropbox isn't configured to accept this report type.
8238 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
8239
8240 final StringBuilder sb = new StringBuilder(1024);
Jeff Sharkeya353d262011-10-28 11:12:06 -07008241 appendDropBoxProcessHeaders(process, processName, sb);
Dan Egnora455d192010-03-12 08:52:28 -08008242 if (activity != null) {
8243 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
8244 }
8245 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
8246 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
8247 }
8248 if (parent != null && parent != activity) {
8249 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
8250 }
8251 if (subject != null) {
8252 sb.append("Subject: ").append(subject).append("\n");
8253 }
8254 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
Christian Lindeberg03d2ca62010-09-28 14:52:20 +02008255 if (Debug.isDebuggerConnected()) {
8256 sb.append("Debugger: Connected\n");
8257 }
Dan Egnora455d192010-03-12 08:52:28 -08008258 sb.append("\n");
8259
8260 // Do the rest in a worker thread to avoid blocking the caller on I/O
8261 // (After this point, we shouldn't access AMS internal data structures.)
8262 Thread worker = new Thread("Error dump: " + dropboxTag) {
8263 @Override
8264 public void run() {
8265 if (report != null) {
8266 sb.append(report);
8267 }
8268 if (logFile != null) {
8269 try {
8270 sb.append(FileUtils.readTextFile(logFile, 128 * 1024, "\n\n[[TRUNCATED]]"));
8271 } catch (IOException e) {
8272 Slog.e(TAG, "Error reading " + logFile, e);
8273 }
8274 }
8275 if (crashInfo != null && crashInfo.stackTrace != null) {
8276 sb.append(crashInfo.stackTrace);
8277 }
8278
8279 String setting = Settings.Secure.ERROR_LOGCAT_PREFIX + dropboxTag;
8280 int lines = Settings.Secure.getInt(mContext.getContentResolver(), setting, 0);
8281 if (lines > 0) {
8282 sb.append("\n");
8283
8284 // Merge several logcat streams, and take the last N lines
8285 InputStreamReader input = null;
8286 try {
8287 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
8288 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
8289 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
8290
8291 try { logcat.getOutputStream().close(); } catch (IOException e) {}
8292 try { logcat.getErrorStream().close(); } catch (IOException e) {}
8293 input = new InputStreamReader(logcat.getInputStream());
8294
8295 int num;
8296 char[] buf = new char[8192];
8297 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
8298 } catch (IOException e) {
8299 Slog.e(TAG, "Error running logcat", e);
8300 } finally {
8301 if (input != null) try { input.close(); } catch (IOException e) {}
8302 }
8303 }
8304
8305 dbox.addText(dropboxTag, sb.toString());
Dan Egnor60d87622009-12-16 16:32:58 -08008306 }
Dan Egnora455d192010-03-12 08:52:28 -08008307 };
8308
Dianne Hackborn56385cc2012-04-30 15:07:47 -07008309 if (process == null) {
8310 // If process is null, we are being called from some internal code
8311 // and may be about to die -- run this synchronously.
8312 worker.run();
Dan Egnora455d192010-03-12 08:52:28 -08008313 } else {
8314 worker.start();
Dan Egnor60d87622009-12-16 16:32:58 -08008315 }
8316 }
8317
8318 /**
8319 * Bring up the "unexpected error" dialog box for a crashing app.
8320 * Deal with edge cases (intercepts from instrumented applications,
8321 * ActivityController, error intent receivers, that sort of thing).
8322 * @param r the application crashing
8323 * @param crashInfo describing the failure
8324 */
8325 private void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008326 long timeMillis = System.currentTimeMillis();
8327 String shortMsg = crashInfo.exceptionClassName;
8328 String longMsg = crashInfo.exceptionMessage;
8329 String stackTrace = crashInfo.stackTrace;
8330 if (shortMsg != null && longMsg != null) {
8331 longMsg = shortMsg + ": " + longMsg;
8332 } else if (shortMsg != null) {
8333 longMsg = shortMsg;
8334 }
8335
Dan Egnor60d87622009-12-16 16:32:58 -08008336 AppErrorResult result = new AppErrorResult();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008337 synchronized (this) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008338 if (mController != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008339 try {
8340 String name = r != null ? r.processName : null;
8341 int pid = r != null ? r.pid : Binder.getCallingPid();
Dan Egnor60d87622009-12-16 16:32:58 -08008342 if (!mController.appCrashed(name, pid,
Dan Egnorb7f03672009-12-09 16:22:32 -08008343 shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008344 Slog.w(TAG, "Force-killing crashed app " + name
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008345 + " at watcher's request");
8346 Process.killProcess(pid);
Dan Egnorb7f03672009-12-09 16:22:32 -08008347 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008348 }
8349 } catch (RemoteException e) {
Dianne Hackbornb06ea702009-07-13 13:07:51 -07008350 mController = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008351 }
8352 }
8353
8354 final long origId = Binder.clearCallingIdentity();
8355
8356 // If this process is running instrumentation, finish it.
8357 if (r != null && r.instrumentationClass != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008358 Slog.w(TAG, "Error in app " + r.processName
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008359 + " running instrumentation " + r.instrumentationClass + ":");
Joe Onorato8a9b2202010-02-26 18:56:32 -08008360 if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
8361 if (longMsg != null) Slog.w(TAG, " " + longMsg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008362 Bundle info = new Bundle();
8363 info.putString("shortMsg", shortMsg);
8364 info.putString("longMsg", longMsg);
8365 finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
8366 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008367 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008368 }
8369
Dan Egnor60d87622009-12-16 16:32:58 -08008370 // If we can't identify the process or it's already exceeded its crash quota,
8371 // quit right away without showing a crash dialog.
8372 if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008373 Binder.restoreCallingIdentity(origId);
Dan Egnorb7f03672009-12-09 16:22:32 -08008374 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008375 }
8376
8377 Message msg = Message.obtain();
8378 msg.what = SHOW_ERROR_MSG;
8379 HashMap data = new HashMap();
8380 data.put("result", result);
8381 data.put("app", r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008382 msg.obj = data;
8383 mHandler.sendMessage(msg);
8384
8385 Binder.restoreCallingIdentity(origId);
8386 }
8387
8388 int res = result.get();
8389
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008390 Intent appErrorIntent = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008391 synchronized (this) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008392 if (r != null && !r.isolated) {
8393 // XXX Can't keep track of crash time for isolated processes,
8394 // since they don't have a persistent identity.
8395 mProcessCrashTimes.put(r.info.processName, r.uid,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008396 SystemClock.uptimeMillis());
8397 }
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008398 if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
Dan Egnorb7f03672009-12-09 16:22:32 -08008399 appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008400 }
8401 }
8402
8403 if (appErrorIntent != null) {
8404 try {
8405 mContext.startActivity(appErrorIntent);
8406 } catch (ActivityNotFoundException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008407 Slog.w(TAG, "bug report receiver dissappeared", e);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008409 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008410 }
Dan Egnorb7f03672009-12-09 16:22:32 -08008411
8412 Intent createAppErrorIntentLocked(ProcessRecord r,
8413 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
8414 ApplicationErrorReport report = createAppErrorReportLocked(r, timeMillis, crashInfo);
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008415 if (report == null) {
8416 return null;
8417 }
8418 Intent result = new Intent(Intent.ACTION_APP_ERROR);
8419 result.setComponent(r.errorReportReceiver);
8420 result.putExtra(Intent.EXTRA_BUG_REPORT, report);
8421 result.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8422 return result;
8423 }
8424
Dan Egnorb7f03672009-12-09 16:22:32 -08008425 private ApplicationErrorReport createAppErrorReportLocked(ProcessRecord r,
8426 long timeMillis, ApplicationErrorReport.CrashInfo crashInfo) {
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008427 if (r.errorReportReceiver == null) {
8428 return null;
8429 }
8430
8431 if (!r.crashing && !r.notResponding) {
8432 return null;
8433 }
8434
Dan Egnorb7f03672009-12-09 16:22:32 -08008435 ApplicationErrorReport report = new ApplicationErrorReport();
8436 report.packageName = r.info.packageName;
8437 report.installerPackageName = r.errorReportReceiver.getPackageName();
8438 report.processName = r.processName;
8439 report.time = timeMillis;
Jacek Surazskie0ee6ef2010-01-07 16:23:03 +01008440 report.systemApp = (r.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008441
Dan Egnorb7f03672009-12-09 16:22:32 -08008442 if (r.crashing) {
8443 report.type = ApplicationErrorReport.TYPE_CRASH;
8444 report.crashInfo = crashInfo;
8445 } else if (r.notResponding) {
8446 report.type = ApplicationErrorReport.TYPE_ANR;
8447 report.anrInfo = new ApplicationErrorReport.AnrInfo();
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008448
Dan Egnorb7f03672009-12-09 16:22:32 -08008449 report.anrInfo.activity = r.notRespondingReport.tag;
8450 report.anrInfo.cause = r.notRespondingReport.shortMsg;
8451 report.anrInfo.info = r.notRespondingReport.longMsg;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008452 }
8453
Dan Egnorb7f03672009-12-09 16:22:32 -08008454 return report;
Jacek Surazskif5b9c722009-05-18 12:09:59 +02008455 }
8456
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008457 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008458 enforceNotIsolatedCaller("getProcessesInErrorState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008459 // assume our apps are happy - lazy create the list
8460 List<ActivityManager.ProcessErrorStateInfo> errList = null;
8461
Dianne Hackborn0c380492012-08-20 17:23:30 -07008462 final boolean allUsers = ActivityManager.checkUidPermission(
8463 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8464 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8465 int userId = UserHandle.getUserId(Binder.getCallingUid());
8466
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008467 synchronized (this) {
8468
8469 // iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008470 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8471 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn0c380492012-08-20 17:23:30 -07008472 if (!allUsers && app.userId != userId) {
8473 continue;
8474 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008475 if ((app.thread != null) && (app.crashing || app.notResponding)) {
8476 // This one's in trouble, so we'll generate a report for it
8477 // crashes are higher priority (in case there's a crash *and* an anr)
8478 ActivityManager.ProcessErrorStateInfo report = null;
8479 if (app.crashing) {
8480 report = app.crashingReport;
8481 } else if (app.notResponding) {
8482 report = app.notRespondingReport;
8483 }
8484
8485 if (report != null) {
8486 if (errList == null) {
8487 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
8488 }
8489 errList.add(report);
8490 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -08008491 Slog.w(TAG, "Missing app error report, app = " + app.processName +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008492 " crashing = " + app.crashing +
8493 " notResponding = " + app.notResponding);
8494 }
8495 }
8496 }
8497 }
8498
8499 return errList;
8500 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07008501
8502 static int oomAdjToImportance(int adj, ActivityManager.RunningAppProcessInfo currApp) {
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008503 if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008504 if (currApp != null) {
8505 currApp.lru = adj - ProcessList.HIDDEN_APP_MIN_ADJ + 1;
8506 }
8507 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008508 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
8509 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008510 } else if (adj >= ProcessList.HOME_APP_ADJ) {
8511 if (currApp != null) {
8512 currApp.lru = 0;
8513 }
8514 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07008515 } else if (adj >= ProcessList.SERVICE_ADJ) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07008516 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
8517 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
8518 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
8519 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
8520 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
8521 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
8522 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
8523 } else {
8524 return ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
8525 }
8526 }
8527
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008528 private void fillInProcMemInfo(ProcessRecord app,
8529 ActivityManager.RunningAppProcessInfo outInfo) {
8530 outInfo.pid = app.pid;
8531 outInfo.uid = app.info.uid;
8532 if (mHeavyWeightProcess == app) {
8533 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
8534 }
8535 if (app.persistent) {
8536 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
8537 }
Dianne Hackborn0c380492012-08-20 17:23:30 -07008538 if (app.hasActivities) {
8539 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
8540 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008541 outInfo.lastTrimLevel = app.trimMemoryLevel;
8542 int adj = app.curAdj;
8543 outInfo.importance = oomAdjToImportance(adj, outInfo);
8544 outInfo.importanceReasonCode = app.adjTypeCode;
8545 }
8546
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008547 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008548 enforceNotIsolatedCaller("getRunningAppProcesses");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008549 // Lazy instantiation of list
8550 List<ActivityManager.RunningAppProcessInfo> runList = null;
Dianne Hackborn0c380492012-08-20 17:23:30 -07008551 final boolean allUsers = ActivityManager.checkUidPermission(
8552 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
8553 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
8554 int userId = UserHandle.getUserId(Binder.getCallingUid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 synchronized (this) {
8556 // Iterate across all processes
Dianne Hackborndd71fc82009-12-16 19:24:32 -08008557 for (int i=mLruProcesses.size()-1; i>=0; i--) {
8558 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn0c380492012-08-20 17:23:30 -07008559 if (!allUsers && app.userId != userId) {
8560 continue;
8561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008562 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
8563 // Generate process state info for running application
8564 ActivityManager.RunningAppProcessInfo currApp =
8565 new ActivityManager.RunningAppProcessInfo(app.processName,
8566 app.pid, app.getPackageList());
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008567 fillInProcMemInfo(app, currApp);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008568 if (app.adjSource instanceof ProcessRecord) {
8569 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008570 currApp.importanceReasonImportance = oomAdjToImportance(
8571 app.adjSourceOom, null);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008572 } else if (app.adjSource instanceof ActivityRecord) {
8573 ActivityRecord r = (ActivityRecord)app.adjSource;
Dianne Hackborndd9b82c2009-09-03 00:18:47 -07008574 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
8575 }
8576 if (app.adjTarget instanceof ComponentName) {
8577 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
8578 }
Joe Onorato8a9b2202010-02-26 18:56:32 -08008579 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008580 // + " lru=" + currApp.lru);
8581 if (runList == null) {
8582 runList = new ArrayList<ActivityManager.RunningAppProcessInfo>();
8583 }
8584 runList.add(currApp);
8585 }
8586 }
8587 }
8588 return runList;
8589 }
8590
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008591 public List<ApplicationInfo> getRunningExternalApplications() {
Dianne Hackborna573f6a2012-02-09 16:12:18 -08008592 enforceNotIsolatedCaller("getRunningExternalApplications");
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008593 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
8594 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
8595 if (runningApps != null && runningApps.size() > 0) {
8596 Set<String> extList = new HashSet<String>();
8597 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
8598 if (app.pkgList != null) {
8599 for (String pkg : app.pkgList) {
8600 extList.add(pkg);
8601 }
8602 }
8603 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07008604 IPackageManager pm = AppGlobals.getPackageManager();
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008605 for (String pkg : extList) {
8606 try {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07008607 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
Suchi Amalapurapuf7f5dda2010-03-23 10:34:28 -07008608 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
8609 retList.add(info);
8610 }
8611 } catch (RemoteException e) {
8612 }
8613 }
8614 }
8615 return retList;
8616 }
8617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008618 @Override
Dianne Hackborn27ff9132012-03-06 14:57:58 -08008619 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
8620 enforceNotIsolatedCaller("getMyMemoryState");
8621 synchronized (this) {
8622 ProcessRecord proc;
8623 synchronized (mPidsSelfLocked) {
8624 proc = mPidsSelfLocked.get(Binder.getCallingPid());
8625 }
8626 fillInProcMemInfo(proc, outInfo);
8627 }
8628 }
8629
8630 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008631 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008632 if (checkCallingPermission(android.Manifest.permission.DUMP)
8633 != PackageManager.PERMISSION_GRANTED) {
8634 pw.println("Permission Denial: can't dump ActivityManager from from pid="
8635 + Binder.getCallingPid()
8636 + ", uid=" + Binder.getCallingUid()
8637 + " without permission "
8638 + android.Manifest.permission.DUMP);
8639 return;
8640 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008641
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008642 boolean dumpAll = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008643 boolean dumpClient = false;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008644 String dumpPackage = null;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008645
8646 int opti = 0;
8647 while (opti < args.length) {
8648 String opt = args[opti];
8649 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
8650 break;
8651 }
8652 opti++;
8653 if ("-a".equals(opt)) {
8654 dumpAll = true;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008655 } else if ("-c".equals(opt)) {
8656 dumpClient = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008657 } else if ("-h".equals(opt)) {
8658 pw.println("Activity manager dump options:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008659 pw.println(" [-a] [-c] [-h] [cmd] ...");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008660 pw.println(" cmd may be one of:");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008661 pw.println(" a[ctivities]: activity stack state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008662 pw.println(" b[roadcasts] [PACKAGE_NAME]: broadcast state");
8663 pw.println(" i[ntents] [PACKAGE_NAME]: pending intent state");
8664 pw.println(" p[rocesses] [PACKAGE_NAME]: process state");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008665 pw.println(" o[om]: out of memory management");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008666 pw.println(" prov[iders] [COMP_SPEC ...]: content provider state");
Marco Nelissen18cb2872011-11-15 11:19:53 -08008667 pw.println(" provider [COMP_SPEC]: provider client-side state");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008668 pw.println(" s[ervices] [COMP_SPEC ...]: service state");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008669 pw.println(" service [COMP_SPEC]: service client-side state");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008670 pw.println(" package [PACKAGE_NAME]: all state related to given package");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008671 pw.println(" all: dump all activities");
8672 pw.println(" top: dump the top activity");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008673 pw.println(" cmd may also be a COMP_SPEC to dump activities.");
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07008674 pw.println(" COMP_SPEC may be a component name (com.foo/.myApp),");
8675 pw.println(" a partial substring in a component name, a");
8676 pw.println(" hex object identifier.");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008677 pw.println(" -a: include all available server state.");
8678 pw.println(" -c: include client state.");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008679 return;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008680 } else {
8681 pw.println("Unknown argument: " + opt + "; use -h for help");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008682 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008683 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008684
8685 long origId = Binder.clearCallingIdentity();
8686 boolean more = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008687 // Is the caller requesting to dump a particular piece of data?
8688 if (opti < args.length) {
8689 String cmd = args[opti];
8690 opti++;
8691 if ("activities".equals(cmd) || "a".equals(cmd)) {
8692 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008693 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008694 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008695 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008696 String[] newArgs;
8697 String name;
8698 if (opti >= args.length) {
8699 name = null;
8700 newArgs = EMPTY_STRING_ARRAY;
8701 } else {
8702 name = args[opti];
8703 opti++;
8704 newArgs = new String[args.length - opti];
8705 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8706 args.length - opti);
8707 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008708 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008709 dumpBroadcastsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008710 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008711 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008712 String[] newArgs;
8713 String name;
8714 if (opti >= args.length) {
8715 name = null;
8716 newArgs = EMPTY_STRING_ARRAY;
8717 } else {
8718 name = args[opti];
8719 opti++;
8720 newArgs = new String[args.length - opti];
8721 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8722 args.length - opti);
8723 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008724 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008725 dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008726 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008727 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008728 String[] newArgs;
8729 String name;
8730 if (opti >= args.length) {
8731 name = null;
8732 newArgs = EMPTY_STRING_ARRAY;
8733 } else {
8734 name = args[opti];
8735 opti++;
8736 newArgs = new String[args.length - opti];
8737 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8738 args.length - opti);
8739 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008740 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008741 dumpProcessesLocked(fd, pw, args, opti, true, name);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008742 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008743 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
8744 synchronized (this) {
8745 dumpOomLocked(fd, pw, args, opti, true);
8746 }
Marco Nelissen18cb2872011-11-15 11:19:53 -08008747 } else if ("provider".equals(cmd)) {
8748 String[] newArgs;
8749 String name;
8750 if (opti >= args.length) {
8751 name = null;
8752 newArgs = EMPTY_STRING_ARRAY;
8753 } else {
8754 name = args[opti];
8755 opti++;
8756 newArgs = new String[args.length - opti];
8757 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
8758 }
8759 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
8760 pw.println("No providers match: " + name);
8761 pw.println("Use -h for help.");
8762 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008763 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
8764 synchronized (this) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008765 dumpProvidersLocked(fd, pw, args, opti, true, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008766 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008767 } else if ("service".equals(cmd)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008768 String[] newArgs;
8769 String name;
8770 if (opti >= args.length) {
8771 name = null;
8772 newArgs = EMPTY_STRING_ARRAY;
8773 } else {
8774 name = args[opti];
8775 opti++;
8776 newArgs = new String[args.length - opti];
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008777 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8778 args.length - opti);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008779 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07008780 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008781 pw.println("No services match: " + name);
8782 pw.println("Use -h for help.");
8783 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008784 } else if ("package".equals(cmd)) {
8785 String[] newArgs;
8786 if (opti >= args.length) {
8787 pw.println("package: no package name specified");
8788 pw.println("Use -h for help.");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008789 } else {
8790 dumpPackage = args[opti];
8791 opti++;
8792 newArgs = new String[args.length - opti];
8793 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
8794 args.length - opti);
8795 args = newArgs;
8796 opti = 0;
Amith Yamasani7463ada2012-04-11 15:02:39 -07008797 more = true;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008798 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008799 } else if ("services".equals(cmd) || "s".equals(cmd)) {
8800 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07008801 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008802 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07008803 } else {
8804 // Dumping a single activity?
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008805 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
8806 pw.println("Bad activity command, or no activities match: " + cmd);
8807 pw.println("Use -h for help.");
Dianne Hackborn625ac272010-09-17 18:29:22 -07008808 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008809 }
8810 if (!more) {
8811 Binder.restoreCallingIdentity(origId);
Dianne Hackborn30d71892010-12-11 10:37:55 -08008812 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008813 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008814 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008815
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008816 // No piece of data specified, dump everything.
8817 synchronized (this) {
8818 boolean needSep;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008819 needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008820 if (needSep) {
8821 pw.println(" ");
8822 }
8823 if (dumpAll) {
8824 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008825 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008826 needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008827 if (needSep) {
8828 pw.println(" ");
8829 }
8830 if (dumpAll) {
8831 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008832 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008833 needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008834 if (needSep) {
8835 pw.println(" ");
8836 }
8837 if (dumpAll) {
8838 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008839 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07008840 needSep = mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008841 if (needSep) {
8842 pw.println(" ");
8843 }
8844 if (dumpAll) {
8845 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008846 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008847 needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008848 if (needSep) {
8849 pw.println(" ");
8850 }
8851 if (dumpAll) {
8852 pw.println("-------------------------------------------------------------------------------");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008853 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008854 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008855 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008856 Binder.restoreCallingIdentity(origId);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008857 }
Amith Yamasani7463ada2012-04-11 15:02:39 -07008858
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008859 boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008860 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008861 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
8862 pw.println(" Main stack:");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008863 dumpHistoryList(fd, pw, mMainStack.mHistory, " ", "Hist", true, !dumpAll, dumpClient,
8864 dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008865 pw.println(" ");
8866 pw.println(" Running activities (most recent first):");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008867 dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
8868 dumpPackage);
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008869 if (mMainStack.mWaitingVisibleActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008870 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008871 pw.println(" Activities waiting for another to become visible:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008872 dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008873 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008874 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008875 if (mMainStack.mStoppingActivities.size() > 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008876 pw.println(" ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008877 pw.println(" Activities waiting to stop:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008878 dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008879 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008880 }
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008881 if (mMainStack.mGoingToSleepActivities.size() > 0) {
8882 pw.println(" ");
8883 pw.println(" Activities waiting to sleep:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008884 dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008885 !dumpAll, false, dumpPackage);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08008886 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008887 if (mMainStack.mFinishingActivities.size() > 0) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008888 pw.println(" ");
8889 pw.println(" Activities waiting to finish:");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008890 dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008891 !dumpAll, false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008892 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008893
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008894 pw.println(" ");
Dianne Hackborn621e2fe2012-02-16 17:07:33 -08008895 if (mMainStack.mPausingActivity != null) {
8896 pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008897 }
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07008898 pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008899 pw.println(" mFocusedActivity: " + mFocusedActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008900 if (dumpAll) {
8901 pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
8902 pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
Dianne Hackborn90c52de2011-09-23 12:57:44 -07008903 pw.println(" mDismissKeyguardOnNextActivity: "
8904 + mMainStack.mDismissKeyguardOnNextActivity);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008905 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008906
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008907 if (mRecentTasks.size() > 0) {
8908 pw.println();
8909 pw.println(" Recent tasks:");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008910
8911 final int N = mRecentTasks.size();
8912 for (int i=0; i<N; i++) {
8913 TaskRecord tr = mRecentTasks.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008914 if (dumpPackage != null) {
8915 if (tr.realActivity == null ||
8916 !dumpPackage.equals(tr.realActivity)) {
8917 continue;
8918 }
8919 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008920 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
8921 pw.println(tr);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008922 if (dumpAll) {
8923 mRecentTasks.get(i).dump(pw, " ");
8924 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008925 }
8926 }
8927
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008928 if (dumpAll) {
8929 pw.println(" ");
8930 pw.println(" mCurTask: " + mCurTask);
8931 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008932
8933 return true;
8934 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07008935
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008936 boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008937 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008938 boolean needSep = false;
8939 int numPers = 0;
8940
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008941 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
8942
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008943 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008944 for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
8945 final int NA = procs.size();
8946 for (int ia=0; ia<NA; ia++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008947 ProcessRecord r = procs.valueAt(ia);
8948 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8949 continue;
8950 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008951 if (!needSep) {
8952 pw.println(" All known processes:");
8953 needSep = true;
8954 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07008955 pw.print(r.persistent ? " *PERS*" : " *APP*");
8956 pw.print(" UID "); pw.print(procs.keyAt(ia));
8957 pw.print(" "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008958 r.dump(pw, " ");
8959 if (r.persistent) {
8960 numPers++;
8961 }
8962 }
8963 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008964 }
Dianne Hackborna0c283e2012-02-09 10:47:01 -08008965
8966 if (mIsolatedProcesses.size() > 0) {
8967 if (needSep) pw.println(" ");
8968 needSep = true;
8969 pw.println(" Isolated process list (sorted by uid):");
8970 for (int i=0; i<mIsolatedProcesses.size(); i++) {
8971 ProcessRecord r = mIsolatedProcesses.valueAt(i);
8972 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8973 continue;
8974 }
8975 pw.println(String.format("%sIsolated #%2d: %s",
8976 " ", i, r.toString()));
8977 }
8978 }
8979
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008980 if (mLruProcesses.size() > 0) {
8981 if (needSep) pw.println(" ");
8982 needSep = true;
Dianne Hackborn905577f2011-09-07 18:31:28 -07008983 pw.println(" Process LRU list (sorted by oom_adj):");
Dianne Hackborn287952c2010-09-22 22:34:31 -07008984 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008985 "Proc", "PERS", false, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08008986 needSep = true;
8987 }
8988
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008989 if (dumpAll) {
8990 synchronized (mPidsSelfLocked) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008991 boolean printed = false;
8992 for (int i=0; i<mPidsSelfLocked.size(); i++) {
8993 ProcessRecord r = mPidsSelfLocked.valueAt(i);
8994 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
8995 continue;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07008996 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08008997 if (!printed) {
8998 if (needSep) pw.println(" ");
8999 needSep = true;
9000 pw.println(" PID mappings:");
9001 printed = true;
9002 }
9003 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
9004 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009005 }
9006 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009007 }
9008
9009 if (mForegroundProcesses.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009010 synchronized (mPidsSelfLocked) {
9011 boolean printed = false;
9012 for (int i=0; i<mForegroundProcesses.size(); i++) {
9013 ProcessRecord r = mPidsSelfLocked.get(
9014 mForegroundProcesses.valueAt(i).pid);
9015 if (dumpPackage != null && (r == null
9016 || !dumpPackage.equals(r.info.packageName))) {
9017 continue;
9018 }
9019 if (!printed) {
9020 if (needSep) pw.println(" ");
9021 needSep = true;
9022 pw.println(" Foreground Processes:");
9023 printed = true;
9024 }
9025 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
9026 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
9027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009028 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009029 }
9030
9031 if (mPersistentStartingProcesses.size() > 0) {
9032 if (needSep) pw.println(" ");
9033 needSep = true;
9034 pw.println(" Persisent processes that are starting:");
9035 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009036 "Starting Norm", "Restarting PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009037 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009038
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009039 if (mRemovedProcesses.size() > 0) {
9040 if (needSep) pw.println(" ");
9041 needSep = true;
9042 pw.println(" Processes that are being removed:");
9043 dumpProcessList(pw, this, mRemovedProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009044 "Removed Norm", "Removed PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009045 }
9046
9047 if (mProcessesOnHold.size() > 0) {
9048 if (needSep) pw.println(" ");
9049 needSep = true;
9050 pw.println(" Processes that are on old until the system is ready:");
9051 dumpProcessList(pw, this, mProcessesOnHold, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009052 "OnHold Norm", "OnHold PERS", dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009053 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009054
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009055 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009056
9057 if (mProcessCrashTimes.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009058 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009059 long now = SystemClock.uptimeMillis();
9060 for (Map.Entry<String, SparseArray<Long>> procs
9061 : mProcessCrashTimes.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009062 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009063 SparseArray<Long> uids = procs.getValue();
9064 final int N = uids.size();
9065 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009066 int puid = uids.keyAt(i);
9067 ProcessRecord r = mProcessNames.get(pname, puid);
9068 if (dumpPackage != null && (r == null
9069 || !dumpPackage.equals(r.info.packageName))) {
9070 continue;
9071 }
9072 if (!printed) {
9073 if (needSep) pw.println(" ");
9074 needSep = true;
9075 pw.println(" Time since processes crashed:");
9076 printed = true;
9077 }
9078 pw.print(" Process "); pw.print(pname);
9079 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009080 pw.print(": last crashed ");
Dianne Hackborn27ff9132012-03-06 14:57:58 -08009081 TimeUtils.formatDuration(now-uids.valueAt(i), pw);
9082 pw.println(" ago");
Dianne Hackbornfd12af42009-08-27 00:44:33 -07009083 }
9084 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009085 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009086
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009087 if (mBadProcesses.getMap().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009088 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009089 for (Map.Entry<String, SparseArray<Long>> procs
9090 : mBadProcesses.getMap().entrySet()) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009091 String pname = procs.getKey();
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009092 SparseArray<Long> uids = procs.getValue();
9093 final int N = uids.size();
9094 for (int i=0; i<N; i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009095 int puid = uids.keyAt(i);
9096 ProcessRecord r = mProcessNames.get(pname, puid);
9097 if (dumpPackage != null && (r == null
9098 || !dumpPackage.equals(r.info.packageName))) {
9099 continue;
9100 }
9101 if (!printed) {
9102 if (needSep) pw.println(" ");
9103 needSep = true;
9104 pw.println(" Bad processes:");
9105 }
9106 pw.print(" Bad process "); pw.print(pname);
9107 pw.print(" uid "); pw.print(puid);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009108 pw.print(": crashed at time ");
9109 pw.println(uids.valueAt(i));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009110 }
9111 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009113
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009114 pw.println();
Dianne Hackborn80a4af22012-08-27 19:18:31 -07009115 pw.println(" mStartedUsers:");
9116 for (int i=0; i<mStartedUsers.size(); i++) {
9117 UserStartedState uss = mStartedUsers.valueAt(i);
9118 pw.print(" User #"); pw.print(uss.mHandle.getIdentifier());
9119 pw.println(":");
9120 uss.dump(" ", pw);
9121 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009122 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009123 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn50685602011-12-01 12:23:37 -08009124 if (dumpAll) {
9125 StringBuilder sb = new StringBuilder(128);
9126 sb.append(" mPreviousProcessVisibleTime: ");
9127 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
9128 pw.println(sb);
9129 }
Dianne Hackborn860755f2010-06-03 18:47:52 -07009130 if (mHeavyWeightProcess != null) {
9131 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9132 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009133 pw.println(" mConfiguration: " + mConfiguration);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009134 if (dumpAll) {
9135 pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
Dianne Hackborn3d0724d2011-05-12 15:39:41 -07009136 if (mCompatModePackages.getPackages().size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009137 boolean printed = false;
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009138 for (Map.Entry<String, Integer> entry
9139 : mCompatModePackages.getPackages().entrySet()) {
9140 String pkg = entry.getKey();
9141 int mode = entry.getValue();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009142 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
9143 continue;
9144 }
9145 if (!printed) {
9146 pw.println(" mScreenCompatPackages:");
9147 printed = true;
9148 }
Dianne Hackborn36cd41f2011-05-25 21:00:46 -07009149 pw.print(" "); pw.print(pkg); pw.print(": ");
9150 pw.print(mode); pw.println();
9151 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -07009152 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009153 }
Dianne Hackbornff5b1582012-04-12 17:24:07 -07009154 if (mSleeping || mWentToSleep || mLockScreenShown) {
9155 pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep
9156 + " mLockScreenShown " + mLockScreenShown);
9157 }
9158 if (mShuttingDown) {
9159 pw.println(" mShuttingDown=" + mShuttingDown);
9160 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009161 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
9162 || mOrigWaitForDebugger) {
9163 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
9164 + " mDebugTransient=" + mDebugTransient
9165 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
9166 }
Siva Velusamy92a8b222012-03-09 16:24:04 -08009167 if (mOpenGlTraceApp != null) {
9168 pw.println(" mOpenGlTraceApp=" + mOpenGlTraceApp);
9169 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07009170 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
9171 || mProfileFd != null) {
9172 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
9173 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
9174 pw.println(" mProfileType=" + mProfileType + " mAutoStopProfiler="
9175 + mAutoStopProfiler);
9176 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009177 if (mAlwaysFinishActivities || mController != null) {
9178 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
9179 + " mController=" + mController);
9180 }
9181 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009182 pw.println(" Total persistent processes: " + numPers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009183 pw.println(" mStartRunning=" + mStartRunning
Dianne Hackborn8891fdc2010-09-20 20:44:46 -07009184 + " mProcessesReady=" + mProcessesReady
9185 + " mSystemReady=" + mSystemReady);
9186 pw.println(" mBooting=" + mBooting
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009187 + " mBooted=" + mBooted
9188 + " mFactoryTest=" + mFactoryTest);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009189 pw.print(" mLastPowerCheckRealtime=");
9190 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
9191 pw.println("");
9192 pw.print(" mLastPowerCheckUptime=");
9193 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
9194 pw.println("");
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -07009195 pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
9196 pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
Dianne Hackborn906497c2010-05-10 15:57:38 -07009197 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
Dianne Hackbornee7621c2012-08-13 16:42:18 -07009198 pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
9199 + " mNumHiddenProcs=" + mNumHiddenProcs
9200 + " mNumServiceProcs=" + mNumServiceProcs
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009201 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009202 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009203
9204 return true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009205 }
9206
Dianne Hackborn287952c2010-09-22 22:34:31 -07009207 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009208 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009209 if (mProcessesToGc.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009210 boolean printed = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009211 long now = SystemClock.uptimeMillis();
9212 for (int i=0; i<mProcessesToGc.size(); i++) {
9213 ProcessRecord proc = mProcessesToGc.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009214 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
9215 continue;
9216 }
9217 if (!printed) {
9218 if (needSep) pw.println(" ");
9219 needSep = true;
9220 pw.println(" Processes that are waiting to GC:");
9221 printed = true;
9222 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009223 pw.print(" Process "); pw.println(proc);
9224 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
9225 pw.print(", last gced=");
9226 pw.print(now-proc.lastRequestedGc);
9227 pw.print(" ms ago, last lowMem=");
9228 pw.print(now-proc.lastLowMemory);
9229 pw.println(" ms ago");
9230
9231 }
9232 }
9233 return needSep;
9234 }
9235
9236 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
9237 int opti, boolean dumpAll) {
9238 boolean needSep = false;
9239
9240 if (mLruProcesses.size() > 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009241 if (needSep) pw.println(" ");
9242 needSep = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009243 pw.println(" OOM levels:");
Dianne Hackborn7d608422011-08-07 16:24:18 -07009244 pw.print(" SYSTEM_ADJ: "); pw.println(ProcessList.SYSTEM_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009245 pw.print(" PERSISTENT_PROC_ADJ: "); pw.println(ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009246 pw.print(" FOREGROUND_APP_ADJ: "); pw.println(ProcessList.FOREGROUND_APP_ADJ);
9247 pw.print(" VISIBLE_APP_ADJ: "); pw.println(ProcessList.VISIBLE_APP_ADJ);
9248 pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(ProcessList.PERCEPTIBLE_APP_ADJ);
9249 pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(ProcessList.HEAVY_WEIGHT_APP_ADJ);
9250 pw.print(" BACKUP_APP_ADJ: "); pw.println(ProcessList.BACKUP_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009251 pw.print(" SERVICE_ADJ: "); pw.println(ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009252 pw.print(" HOME_APP_ADJ: "); pw.println(ProcessList.HOME_APP_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009253 pw.print(" PREVIOUS_APP_ADJ: "); pw.println(ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009254 pw.print(" SERVICE_B_ADJ: "); pw.println(ProcessList.SERVICE_B_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009255 pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009256 pw.print(" HIDDEN_APP_MAX_ADJ: "); pw.println(ProcessList.HIDDEN_APP_MAX_ADJ);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009257
9258 if (needSep) pw.println(" ");
9259 needSep = true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009260 pw.println(" Process OOM control:");
Dianne Hackborn905577f2011-09-07 18:31:28 -07009261 dumpProcessOomList(pw, this, mLruProcesses, " ",
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009262 "Proc", "PERS", true, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009263 needSep = true;
9264 }
9265
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009266 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009267
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009268 pw.println();
Dianne Hackborn287952c2010-09-22 22:34:31 -07009269 pw.println(" mHomeProcess: " + mHomeProcess);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009270 pw.println(" mPreviousProcess: " + mPreviousProcess);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009271 if (mHeavyWeightProcess != null) {
9272 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
9273 }
9274
9275 return true;
9276 }
9277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009278 /**
9279 * There are three ways to call this:
Marco Nelissen18cb2872011-11-15 11:19:53 -08009280 * - no provider specified: dump all the providers
9281 * - a flattened component name that matched an existing provider was specified as the
9282 * first arg: dump that one provider
9283 * - the first arg isn't the flattened component name of an existing provider:
9284 * dump all providers whose component contains the first arg as a substring
9285 */
9286 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9287 int opti, boolean dumpAll) {
Marco Nelissende7408c2012-02-08 14:57:38 -08009288 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
Marco Nelissen18cb2872011-11-15 11:19:53 -08009289 }
9290
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009291 static class ItemMatcher {
9292 ArrayList<ComponentName> components;
9293 ArrayList<String> strings;
9294 ArrayList<Integer> objects;
9295 boolean all;
9296
9297 ItemMatcher() {
9298 all = true;
9299 }
9300
9301 void build(String name) {
9302 ComponentName componentName = ComponentName.unflattenFromString(name);
9303 if (componentName != null) {
9304 if (components == null) {
9305 components = new ArrayList<ComponentName>();
9306 }
9307 components.add(componentName);
9308 all = false;
9309 } else {
9310 int objectId = 0;
9311 // Not a '/' separated full component name; maybe an object ID?
9312 try {
9313 objectId = Integer.parseInt(name, 16);
9314 if (objects == null) {
9315 objects = new ArrayList<Integer>();
9316 }
9317 objects.add(objectId);
9318 all = false;
9319 } catch (RuntimeException e) {
9320 // Not an integer; just do string match.
9321 if (strings == null) {
9322 strings = new ArrayList<String>();
9323 }
9324 strings.add(name);
9325 all = false;
9326 }
9327 }
9328 }
9329
9330 int build(String[] args, int opti) {
9331 for (; opti<args.length; opti++) {
9332 String name = args[opti];
9333 if ("--".equals(name)) {
9334 return opti+1;
9335 }
9336 build(name);
9337 }
9338 return opti;
9339 }
9340
9341 boolean match(Object object, ComponentName comp) {
9342 if (all) {
9343 return true;
9344 }
9345 if (components != null) {
9346 for (int i=0; i<components.size(); i++) {
9347 if (components.get(i).equals(comp)) {
9348 return true;
9349 }
9350 }
9351 }
9352 if (objects != null) {
9353 for (int i=0; i<objects.size(); i++) {
9354 if (System.identityHashCode(object) == objects.get(i)) {
9355 return true;
9356 }
9357 }
9358 }
9359 if (strings != null) {
9360 String flat = comp.flattenToString();
9361 for (int i=0; i<strings.size(); i++) {
9362 if (flat.contains(strings.get(i))) {
9363 return true;
9364 }
9365 }
9366 }
9367 return false;
9368 }
9369 }
9370
Dianne Hackborn625ac272010-09-17 18:29:22 -07009371 /**
9372 * There are three things that cmd can be:
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009373 * - a flattened component name that matches an existing activity
Dianne Hackborn625ac272010-09-17 18:29:22 -07009374 * - the cmd arg isn't the flattened component name of an existing activity:
9375 * dump all activity whose component contains the cmd as a substring
9376 * - A hex number of the ActivityRecord object instance.
9377 */
9378 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
9379 int opti, boolean dumpAll) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009380 ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009381
9382 if ("all".equals(name)) {
9383 synchronized (this) {
9384 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07009385 activities.add(r1);
9386 }
9387 }
Dianne Hackbornf9302322011-06-14 18:36:14 -07009388 } else if ("top".equals(name)) {
9389 synchronized (this) {
9390 final int N = mMainStack.mHistory.size();
9391 if (N > 0) {
9392 activities.add((ActivityRecord)mMainStack.mHistory.get(N-1));
9393 }
9394 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009395 } else {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009396 ItemMatcher matcher = new ItemMatcher();
9397 matcher.build(name);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009398
9399 synchronized (this) {
9400 for (ActivityRecord r1 : (ArrayList<ActivityRecord>)mMainStack.mHistory) {
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009401 if (matcher.match(r1, r1.intent.getComponent())) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009402 activities.add(r1);
9403 }
9404 }
9405 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009406 }
9407
9408 if (activities.size() <= 0) {
9409 return false;
9410 }
9411
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009412 String[] newArgs = new String[args.length - opti];
9413 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
9414
Dianne Hackborn30d71892010-12-11 10:37:55 -08009415 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009416 boolean needSep = false;
Dianne Hackborn30d71892010-12-11 10:37:55 -08009417 for (int i=activities.size()-1; i>=0; i--) {
9418 ActivityRecord r = (ActivityRecord)activities.get(i);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009419 if (needSep) {
9420 pw.println();
9421 }
9422 needSep = true;
9423 synchronized (this) {
9424 if (lastTask != r.task) {
9425 lastTask = r.task;
9426 pw.print("TASK "); pw.print(lastTask.affinity);
9427 pw.print(" id="); pw.println(lastTask.taskId);
9428 if (dumpAll) {
9429 lastTask.dump(pw, " ");
9430 }
Dianne Hackborn30d71892010-12-11 10:37:55 -08009431 }
9432 }
9433 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009434 }
9435 return true;
9436 }
9437
9438 /**
9439 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
9440 * there is a thread associated with the activity.
9441 */
Dianne Hackborn30d71892010-12-11 10:37:55 -08009442 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009443 final ActivityRecord r, String[] args, boolean dumpAll) {
9444 String innerPrefix = prefix + " ";
Dianne Hackborn30d71892010-12-11 10:37:55 -08009445 synchronized (this) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009446 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
9447 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
9448 pw.print(" pid=");
Dianne Hackborn30d71892010-12-11 10:37:55 -08009449 if (r.app != null) pw.println(r.app.pid);
9450 else pw.println("(not running)");
9451 if (dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009452 r.dump(pw, innerPrefix);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009453 }
Dianne Hackborn625ac272010-09-17 18:29:22 -07009454 }
9455 if (r.app != null && r.app.thread != null) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009456 // flush anything that is already in the PrintWriter since the thread is going
9457 // to write to the file descriptor directly
9458 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07009459 try {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009460 TransferPipe tp = new TransferPipe();
9461 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009462 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9463 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009464 tp.go(fd);
9465 } finally {
9466 tp.kill();
9467 }
9468 } catch (IOException e) {
9469 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
Dianne Hackborn625ac272010-09-17 18:29:22 -07009470 } catch (RemoteException e) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009471 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
Dianne Hackborn625ac272010-09-17 18:29:22 -07009472 }
9473 }
9474 }
9475
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009476 boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009477 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009478 boolean needSep = false;
Dianne Hackborn786b4402012-08-27 15:14:02 -07009479 boolean onlyHistory = false;
9480
9481 if ("history".equals(dumpPackage)) {
9482 onlyHistory = true;
9483 dumpPackage = null;
9484 }
9485
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009486 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
Dianne Hackborn786b4402012-08-27 15:14:02 -07009487 if (!onlyHistory && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009488 if (mRegisteredReceivers.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009489 boolean printed = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009490 Iterator it = mRegisteredReceivers.values().iterator();
9491 while (it.hasNext()) {
9492 ReceiverList r = (ReceiverList)it.next();
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009493 if (dumpPackage != null && (r.app == null ||
9494 !dumpPackage.equals(r.app.info.packageName))) {
9495 continue;
9496 }
9497 if (!printed) {
9498 pw.println(" Registered Receivers:");
9499 needSep = true;
9500 printed = true;
9501 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009502 pw.print(" * "); pw.println(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009503 r.dump(pw, " ");
9504 }
9505 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009506
9507 if (mReceiverResolver.dump(pw, needSep ?
9508 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
9509 " ", dumpPackage, false)) {
9510 needSep = true;
9511 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009512 }
Christopher Tatef46723b2012-01-26 14:19:24 -08009513
9514 for (BroadcastQueue q : mBroadcastQueues) {
9515 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009516 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009517
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009518 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009519
Dianne Hackborn786b4402012-08-27 15:14:02 -07009520 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07009521 for (int user=0; user<mStickyBroadcasts.size(); user++) {
9522 if (needSep) {
9523 pw.println();
9524 }
9525 needSep = true;
9526 pw.print(" Sticky broadcasts for user ");
9527 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
9528 StringBuilder sb = new StringBuilder(128);
9529 for (Map.Entry<String, ArrayList<Intent>> ent
9530 : mStickyBroadcasts.valueAt(user).entrySet()) {
9531 pw.print(" * Sticky action "); pw.print(ent.getKey());
9532 if (dumpAll) {
9533 pw.println(":");
9534 ArrayList<Intent> intents = ent.getValue();
9535 final int N = intents.size();
9536 for (int i=0; i<N; i++) {
9537 sb.setLength(0);
9538 sb.append(" Intent: ");
9539 intents.get(i).toShortString(sb, false, true, false, false);
9540 pw.println(sb.toString());
9541 Bundle bundle = intents.get(i).getExtras();
9542 if (bundle != null) {
9543 pw.print(" ");
9544 pw.println(bundle.toString());
9545 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009546 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07009547 } else {
9548 pw.println("");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009549 }
9550 }
9551 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009552 }
9553
Dianne Hackborn786b4402012-08-27 15:14:02 -07009554 if (!onlyHistory && dumpAll) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009555 pw.println();
Christopher Tatef46723b2012-01-26 14:19:24 -08009556 for (BroadcastQueue queue : mBroadcastQueues) {
9557 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
9558 + queue.mBroadcastsScheduled);
9559 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009560 pw.println(" mHandler:");
9561 mHandler.dump(new PrintWriterPrinter(pw), " ");
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009562 needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009563 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009564
9565 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009566 }
9567
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009568 boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009569 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackborn9da2d402012-03-15 13:43:08 -07009570 boolean needSep = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009571
Dianne Hackborn1c9b2602011-08-19 14:08:43 -07009572 ItemMatcher matcher = new ItemMatcher();
9573 matcher.build(args, opti);
9574
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009575 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
Amith Yamasani742a6712011-05-04 14:49:28 -07009576
9577 mProviderMap.dumpProvidersLocked(pw, dumpAll);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009578
9579 if (mLaunchingProviders.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009580 boolean printed = false;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009581 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009582 ContentProviderRecord r = mLaunchingProviders.get(i);
9583 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
9584 continue;
9585 }
9586 if (!printed) {
9587 if (needSep) pw.println(" ");
9588 needSep = true;
9589 pw.println(" Launching content providers:");
9590 printed = true;
9591 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009592 pw.print(" Launching #"); pw.print(i); pw.print(": ");
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009593 pw.println(r);
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009594 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009595 }
9596
9597 if (mGrantedUriPermissions.size() > 0) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009598 if (needSep) pw.println();
9599 needSep = true;
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009600 pw.println("Granted Uri Permissions:");
9601 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
9602 int uid = mGrantedUriPermissions.keyAt(i);
9603 HashMap<Uri, UriPermission> perms
9604 = mGrantedUriPermissions.valueAt(i);
9605 pw.print(" * UID "); pw.print(uid);
9606 pw.println(" holds:");
9607 for (UriPermission perm : perms.values()) {
9608 pw.print(" "); pw.println(perm);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009609 if (dumpAll) {
9610 perm.dump(pw, " ");
9611 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009612 }
9613 }
9614 needSep = true;
9615 }
9616
9617 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009618 }
9619
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009620 boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009621 int opti, boolean dumpAll, String dumpPackage) {
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009622 boolean needSep = false;
9623
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009624 if (mIntentSenderRecords.size() > 0) {
9625 boolean printed = false;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009626 Iterator<WeakReference<PendingIntentRecord>> it
9627 = mIntentSenderRecords.values().iterator();
9628 while (it.hasNext()) {
9629 WeakReference<PendingIntentRecord> ref = it.next();
9630 PendingIntentRecord rec = ref != null ? ref.get(): null;
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009631 if (dumpPackage != null && (rec == null
9632 || !dumpPackage.equals(rec.key.packageName))) {
9633 continue;
9634 }
9635 if (!printed) {
9636 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
9637 printed = true;
9638 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009639 needSep = true;
9640 if (rec != null) {
9641 pw.print(" * "); pw.println(rec);
9642 if (dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009643 rec.dump(pw, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009644 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009645 } else {
9646 pw.print(" * "); pw.println(ref);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009647 }
9648 }
9649 }
Dianne Hackbornc59411b2009-12-21 20:10:14 -08009650
9651 return needSep;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009652 }
9653
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009654 private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009655 String prefix, String label, boolean complete, boolean brief, boolean client,
9656 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009657 TaskRecord lastTask = null;
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009658 boolean needNL = false;
9659 final String innerPrefix = prefix + " ";
9660 final String[] args = new String[0];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009661 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009662 final ActivityRecord r = (ActivityRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009663 if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
9664 continue;
9665 }
Dianne Hackbornf26fd992011-04-08 18:14:09 -07009666 final boolean full = !brief && (complete || !r.isInHistory());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009667 if (needNL) {
9668 pw.println(" ");
9669 needNL = false;
9670 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009671 if (lastTask != r.task) {
9672 lastTask = r.task;
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009673 pw.print(prefix);
9674 pw.print(full ? "* " : " ");
9675 pw.println(lastTask);
9676 if (full) {
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009677 lastTask.dump(pw, prefix + " ");
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009678 } else if (complete) {
9679 // Complete + brief == give a summary. Isn't that obvious?!?
9680 if (lastTask.intent != null) {
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009681 pw.print(prefix); pw.print(" ");
Dianne Hackborn21c241e2012-03-08 13:57:23 -08009682 pw.println(lastTask.intent.toInsecureStringWithClip());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009683 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009685 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009686 pw.print(prefix); pw.print(full ? " * " : " "); pw.print(label);
9687 pw.print(" #"); pw.print(i); pw.print(": ");
9688 pw.println(r);
9689 if (full) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009690 r.dump(pw, innerPrefix);
9691 } else if (complete) {
9692 // Complete + brief == give a summary. Isn't that obvious?!?
Dianne Hackborn90c52de2011-09-23 12:57:44 -07009693 pw.print(innerPrefix); pw.println(r.intent.toInsecureString());
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009694 if (r.app != null) {
9695 pw.print(innerPrefix); pw.println(r.app);
9696 }
9697 }
9698 if (client && r.app != null && r.app.thread != null) {
9699 // flush anything that is already in the PrintWriter since the thread is going
9700 // to write to the file descriptor directly
9701 pw.flush();
9702 try {
9703 TransferPipe tp = new TransferPipe();
9704 try {
Dianne Hackbornbe707852011-11-11 14:32:10 -08009705 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
9706 r.appToken, innerPrefix, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009707 // Short timeout, since blocking here can
9708 // deadlock with the application.
9709 tp.go(fd, 2000);
9710 } finally {
9711 tp.kill();
9712 }
9713 } catch (IOException e) {
9714 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
9715 } catch (RemoteException e) {
9716 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
9717 }
9718 needNL = true;
Dianne Hackbornf210d6b2009-04-13 18:42:49 -07009719 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009720 }
9721 }
9722
Dianne Hackborn09c916b2009-12-08 14:50:51 -08009723 private static String buildOomTag(String prefix, String space, int val, int base) {
9724 if (val == base) {
9725 if (space == null) return prefix;
9726 return prefix + " ";
9727 }
9728 return prefix + "+" + Integer.toString(val-base);
9729 }
9730
9731 private static final int dumpProcessList(PrintWriter pw,
9732 ActivityManagerService service, List list,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009733 String prefix, String normalLabel, String persistentLabel,
9734 String dumpPackage) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009735 int numPers = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009736 final int N = list.size()-1;
9737 for (int i=N; i>=0; i--) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009738 ProcessRecord r = (ProcessRecord)list.get(i);
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009739 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9740 continue;
9741 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07009742 pw.println(String.format("%s%s #%2d: %s",
9743 prefix, (r.persistent ? persistentLabel : normalLabel),
9744 i, r.toString()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009745 if (r.persistent) {
9746 numPers++;
9747 }
9748 }
9749 return numPers;
9750 }
9751
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009752 private static final boolean dumpProcessOomList(PrintWriter pw,
Dianne Hackborn905577f2011-09-07 18:31:28 -07009753 ActivityManagerService service, List<ProcessRecord> origList,
Dianne Hackborn287952c2010-09-22 22:34:31 -07009754 String prefix, String normalLabel, String persistentLabel,
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009755 boolean inclDetails, String dumpPackage) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07009756
Dianne Hackborn905577f2011-09-07 18:31:28 -07009757 ArrayList<Pair<ProcessRecord, Integer>> list
9758 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
9759 for (int i=0; i<origList.size(); i++) {
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009760 ProcessRecord r = origList.get(i);
9761 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
9762 continue;
9763 }
Dianne Hackborn905577f2011-09-07 18:31:28 -07009764 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
9765 }
9766
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009767 if (list.size() <= 0) {
9768 return false;
9769 }
9770
Dianne Hackborn905577f2011-09-07 18:31:28 -07009771 Comparator<Pair<ProcessRecord, Integer>> comparator
9772 = new Comparator<Pair<ProcessRecord, Integer>>() {
9773 @Override
9774 public int compare(Pair<ProcessRecord, Integer> object1,
9775 Pair<ProcessRecord, Integer> object2) {
9776 if (object1.first.setAdj != object2.first.setAdj) {
9777 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
9778 }
9779 if (object1.second.intValue() != object2.second.intValue()) {
9780 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
9781 }
9782 return 0;
9783 }
9784 };
9785
9786 Collections.sort(list, comparator);
9787
Dianne Hackborn287952c2010-09-22 22:34:31 -07009788 final long curRealtime = SystemClock.elapsedRealtime();
9789 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
9790 final long curUptime = SystemClock.uptimeMillis();
9791 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
9792
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009793 for (int i=list.size()-1; i>=0; i--) {
Dianne Hackborn905577f2011-09-07 18:31:28 -07009794 ProcessRecord r = list.get(i).first;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009795 String oomAdj;
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009796 if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn7d608422011-08-07 16:24:18 -07009797 oomAdj = buildOomTag("bak", " ", r.setAdj, ProcessList.HIDDEN_APP_MIN_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009798 } else if (r.setAdj >= ProcessList.SERVICE_B_ADJ) {
9799 oomAdj = buildOomTag("svcb ", null, r.setAdj, ProcessList.SERVICE_B_ADJ);
Dianne Hackbornf35fe232011-11-01 19:25:20 -07009800 } else if (r.setAdj >= ProcessList.PREVIOUS_APP_ADJ) {
9801 oomAdj = buildOomTag("prev ", null, r.setAdj, ProcessList.PREVIOUS_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009802 } else if (r.setAdj >= ProcessList.HOME_APP_ADJ) {
9803 oomAdj = buildOomTag("home ", null, r.setAdj, ProcessList.HOME_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009804 } else if (r.setAdj >= ProcessList.SERVICE_ADJ) {
9805 oomAdj = buildOomTag("svc ", null, r.setAdj, ProcessList.SERVICE_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009806 } else if (r.setAdj >= ProcessList.BACKUP_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -08009807 oomAdj = buildOomTag("bkup ", null, r.setAdj, ProcessList.BACKUP_APP_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009808 } else if (r.setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
9809 oomAdj = buildOomTag("hvy ", null, r.setAdj, ProcessList.HEAVY_WEIGHT_APP_ADJ);
9810 } else if (r.setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
9811 oomAdj = buildOomTag("prcp ", null, r.setAdj, ProcessList.PERCEPTIBLE_APP_ADJ);
9812 } else if (r.setAdj >= ProcessList.VISIBLE_APP_ADJ) {
9813 oomAdj = buildOomTag("vis ", null, r.setAdj, ProcessList.VISIBLE_APP_ADJ);
9814 } else if (r.setAdj >= ProcessList.FOREGROUND_APP_ADJ) {
9815 oomAdj = buildOomTag("fore ", null, r.setAdj, ProcessList.FOREGROUND_APP_ADJ);
Dianne Hackborne02c88a2011-10-28 13:58:15 -07009816 } else if (r.setAdj >= ProcessList.PERSISTENT_PROC_ADJ) {
9817 oomAdj = buildOomTag("pers ", null, r.setAdj, ProcessList.PERSISTENT_PROC_ADJ);
Dianne Hackborn7d608422011-08-07 16:24:18 -07009818 } else if (r.setAdj >= ProcessList.SYSTEM_ADJ) {
9819 oomAdj = buildOomTag("sys ", null, r.setAdj, ProcessList.SYSTEM_ADJ);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009820 } else {
9821 oomAdj = Integer.toString(r.setAdj);
9822 }
9823 String schedGroup;
9824 switch (r.setSchedGroup) {
9825 case Process.THREAD_GROUP_BG_NONINTERACTIVE:
9826 schedGroup = "B";
9827 break;
9828 case Process.THREAD_GROUP_DEFAULT:
9829 schedGroup = "F";
9830 break;
9831 default:
9832 schedGroup = Integer.toString(r.setSchedGroup);
9833 break;
9834 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -07009835 String foreground;
9836 if (r.foregroundActivities) {
9837 foreground = "A";
9838 } else if (r.foregroundServices) {
9839 foreground = "S";
9840 } else {
9841 foreground = " ";
9842 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07009843 pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
Dianne Hackborn287952c2010-09-22 22:34:31 -07009844 prefix, (r.persistent ? persistentLabel : normalLabel),
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009845 (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
9846 foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
Dianne Hackborn287952c2010-09-22 22:34:31 -07009847 if (r.adjSource != null || r.adjTarget != null) {
9848 pw.print(prefix);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009849 pw.print(" ");
Dianne Hackborn287952c2010-09-22 22:34:31 -07009850 if (r.adjTarget instanceof ComponentName) {
9851 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
9852 } else if (r.adjTarget != null) {
9853 pw.print(r.adjTarget.toString());
9854 } else {
9855 pw.print("{null}");
9856 }
9857 pw.print("<=");
9858 if (r.adjSource instanceof ProcessRecord) {
9859 pw.print("Proc{");
9860 pw.print(((ProcessRecord)r.adjSource).toShortString());
9861 pw.println("}");
9862 } else if (r.adjSource != null) {
9863 pw.println(r.adjSource.toString());
9864 } else {
9865 pw.println("{null}");
9866 }
9867 }
9868 if (inclDetails) {
9869 pw.print(prefix);
9870 pw.print(" ");
9871 pw.print("oom: max="); pw.print(r.maxAdj);
9872 pw.print(" hidden="); pw.print(r.hiddenAdj);
Dianne Hackbornee7621c2012-08-13 16:42:18 -07009873 pw.print(" empty="); pw.print(r.emptyAdj);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009874 pw.print(" curRaw="); pw.print(r.curRawAdj);
9875 pw.print(" setRaw="); pw.print(r.setRawAdj);
9876 pw.print(" cur="); pw.print(r.curAdj);
9877 pw.print(" set="); pw.println(r.setAdj);
9878 pw.print(prefix);
9879 pw.print(" ");
9880 pw.print("keeping="); pw.print(r.keeping);
9881 pw.print(" hidden="); pw.print(r.hidden);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07009882 pw.print(" empty="); pw.print(r.empty);
9883 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
Dianne Hackborn287952c2010-09-22 22:34:31 -07009884
9885 if (!r.keeping) {
9886 if (r.lastWakeTime != 0) {
9887 long wtime;
9888 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
9889 synchronized (stats) {
9890 wtime = stats.getProcessWakeTime(r.info.uid,
9891 r.pid, curRealtime);
9892 }
9893 long timeUsed = wtime - r.lastWakeTime;
9894 pw.print(prefix);
9895 pw.print(" ");
9896 pw.print("keep awake over ");
9897 TimeUtils.formatDuration(realtimeSince, pw);
9898 pw.print(" used ");
9899 TimeUtils.formatDuration(timeUsed, pw);
9900 pw.print(" (");
9901 pw.print((timeUsed*100)/realtimeSince);
9902 pw.println("%)");
9903 }
9904 if (r.lastCpuTime != 0) {
9905 long timeUsed = r.curCpuTime - r.lastCpuTime;
9906 pw.print(prefix);
9907 pw.print(" ");
9908 pw.print("run cpu over ");
9909 TimeUtils.formatDuration(uptimeSince, pw);
9910 pw.print(" used ");
9911 TimeUtils.formatDuration(timeUsed, pw);
9912 pw.print(" (");
9913 pw.print((timeUsed*100)/uptimeSince);
9914 pw.println("%)");
9915 }
9916 }
9917 }
9918 }
Dianne Hackbornee9aef02011-11-16 13:21:46 -08009919 return true;
Dianne Hackborn287952c2010-09-22 22:34:31 -07009920 }
9921
Dianne Hackbornb437e092011-08-05 17:50:29 -07009922 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009923 ArrayList<ProcessRecord> procs;
9924 synchronized (this) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009925 if (args != null && args.length > start
9926 && args[start].charAt(0) != '-') {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009927 procs = new ArrayList<ProcessRecord>();
9928 int pid = -1;
9929 try {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009930 pid = Integer.parseInt(args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009931 } catch (NumberFormatException e) {
9932
9933 }
9934 for (int i=mLruProcesses.size()-1; i>=0; i--) {
9935 ProcessRecord proc = mLruProcesses.get(i);
9936 if (proc.pid == pid) {
9937 procs.add(proc);
Dianne Hackbornb437e092011-08-05 17:50:29 -07009938 } else if (proc.processName.equals(args[start])) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009939 procs.add(proc);
9940 }
9941 }
9942 if (procs.size() <= 0) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009943 pw.println("No process found for: " + args[start]);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009944 return null;
9945 }
9946 } else {
9947 procs = new ArrayList<ProcessRecord>(mLruProcesses);
9948 }
9949 }
9950 return procs;
9951 }
9952
9953 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
9954 PrintWriter pw, String[] args) {
Dianne Hackbornb437e092011-08-05 17:50:29 -07009955 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009956 if (procs == null) {
9957 return;
9958 }
9959
9960 long uptime = SystemClock.uptimeMillis();
9961 long realtime = SystemClock.elapsedRealtime();
9962 pw.println("Applications Graphics Acceleration Info:");
9963 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
9964
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009965 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9966 ProcessRecord r = procs.get(i);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009967 if (r.thread != null) {
9968 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
9969 pw.flush();
9970 try {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009971 TransferPipe tp = new TransferPipe();
9972 try {
9973 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
9974 tp.go(fd);
9975 } finally {
9976 tp.kill();
9977 }
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009978 } catch (IOException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009979 pw.println("Failure while dumping the app: " + r);
Dianne Hackborne17aeb32011-04-07 15:11:57 -07009980 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -07009981 } catch (RemoteException e) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07009982 pw.println("Got a RemoteException while dumping the app " + r);
Chet Haase9c1e23b2011-03-24 10:51:31 -07009983 pw.flush();
9984 }
9985 }
9986 }
Chet Haase9c1e23b2011-03-24 10:51:31 -07009987 }
9988
Jeff Brown6754ba22011-12-14 20:20:01 -08009989 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
9990 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, args);
9991 if (procs == null) {
9992 return;
9993 }
9994
9995 pw.println("Applications Database Info:");
9996
9997 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
9998 ProcessRecord r = procs.get(i);
9999 if (r.thread != null) {
10000 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
10001 pw.flush();
10002 try {
10003 TransferPipe tp = new TransferPipe();
10004 try {
10005 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
10006 tp.go(fd);
10007 } finally {
10008 tp.kill();
10009 }
10010 } catch (IOException e) {
10011 pw.println("Failure while dumping the app: " + r);
10012 pw.flush();
10013 } catch (RemoteException e) {
10014 pw.println("Got a RemoteException while dumping the app " + r);
10015 pw.flush();
10016 }
10017 }
10018 }
10019 }
10020
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010021 final static class MemItem {
10022 final String label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010023 final String shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010024 final long pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010025 final int id;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010026 ArrayList<MemItem> subitems;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010027
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010028 public MemItem(String _label, String _shortLabel, long _pss, int _id) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010029 label = _label;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010030 shortLabel = _shortLabel;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010031 pss = _pss;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010032 id = _id;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010033 }
10034 }
10035
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010036 static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items,
Dianne Hackbornb437e092011-08-05 17:50:29 -070010037 boolean sort) {
10038 if (sort) {
10039 Collections.sort(items, new Comparator<MemItem>() {
10040 @Override
10041 public int compare(MemItem lhs, MemItem rhs) {
10042 if (lhs.pss < rhs.pss) {
10043 return 1;
10044 } else if (lhs.pss > rhs.pss) {
10045 return -1;
10046 }
10047 return 0;
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010048 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010049 });
10050 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010051
10052 for (int i=0; i<items.size(); i++) {
10053 MemItem mi = items.get(i);
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010054 pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010055 if (mi.subitems != null) {
10056 dumpMemItems(pw, prefix + " ", mi.subitems, true);
10057 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010058 }
10059 }
10060
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010061 // These are in KB.
10062 static final long[] DUMP_MEM_BUCKETS = new long[] {
10063 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
10064 120*1024, 160*1024, 200*1024,
10065 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
10066 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
10067 };
10068
Dianne Hackborn672342c2011-11-29 11:29:02 -080010069 static final void appendMemBucket(StringBuilder out, long memKB, String label,
10070 boolean stackLike) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010071 int start = label.lastIndexOf('.');
10072 if (start >= 0) start++;
10073 else start = 0;
10074 int end = label.length();
10075 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
10076 if (DUMP_MEM_BUCKETS[i] >= memKB) {
10077 long bucket = DUMP_MEM_BUCKETS[i]/1024;
10078 out.append(bucket);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010079 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010080 out.append(label, start, end);
10081 return;
10082 }
10083 }
10084 out.append(memKB/1024);
Dianne Hackborn672342c2011-11-29 11:29:02 -080010085 out.append(stackLike ? "MB." : "MB ");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010086 out.append(label, start, end);
10087 }
10088
10089 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
10090 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ,
10091 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
10092 ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
10093 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ
10094 };
10095 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
10096 "System", "Persistent", "Foreground",
10097 "Visible", "Perceptible", "Heavy Weight",
10098 "Backup", "A Services", "Home", "Previous",
10099 "B Services", "Background"
10100 };
10101
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010102 final void dumpApplicationMemoryUsage(FileDescriptor fd,
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010103 PrintWriter pw, String prefix, String[] args, boolean brief,
Dianne Hackborn672342c2011-11-29 11:29:02 -080010104 PrintWriter categoryPw, StringBuilder outTag, StringBuilder outStack) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010105 boolean dumpAll = false;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010106 boolean oomOnly = false;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010107
10108 int opti = 0;
10109 while (opti < args.length) {
10110 String opt = args[opti];
10111 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
10112 break;
10113 }
10114 opti++;
10115 if ("-a".equals(opt)) {
10116 dumpAll = true;
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010117 } else if ("--oom".equals(opt)) {
10118 oomOnly = true;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010119 } else if ("-h".equals(opt)) {
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010120 pw.println("meminfo dump options: [-a] [--oom] [process]");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010121 pw.println(" -a: include all available information for each process.");
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010122 pw.println(" --oom: only show processes organized by oom adj.");
Dianne Hackbornb437e092011-08-05 17:50:29 -070010123 pw.println("If [process] is specified it can be the name or ");
10124 pw.println("pid of a specific process to dump.");
10125 return;
10126 } else {
10127 pw.println("Unknown argument: " + opt + "; use -h for help");
10128 }
10129 }
10130
10131 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, args);
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010132 if (procs == null) {
10133 return;
10134 }
10135
Dianne Hackborn6447ca32009-04-07 19:50:08 -070010136 final boolean isCheckinRequest = scanArgs(args, "--checkin");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010137 long uptime = SystemClock.uptimeMillis();
10138 long realtime = SystemClock.elapsedRealtime();
Dianne Hackbornb437e092011-08-05 17:50:29 -070010139
10140 if (procs.size() == 1 || isCheckinRequest) {
10141 dumpAll = true;
10142 }
10143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010144 if (isCheckinRequest) {
10145 // short checkin version
10146 pw.println(uptime + "," + realtime);
10147 pw.flush();
10148 } else {
10149 pw.println("Applications Memory Usage (kB):");
10150 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
10151 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010152
Dianne Hackbornb437e092011-08-05 17:50:29 -070010153 String[] innerArgs = new String[args.length-opti];
10154 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
10155
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010156 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
10157 long nativePss=0, dalvikPss=0, otherPss=0;
10158 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
10159
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010160 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
10161 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
10162 new ArrayList[DUMP_MEM_OOM_LABEL.length];
Dianne Hackbornb437e092011-08-05 17:50:29 -070010163
10164 long totalPss = 0;
10165
Dianne Hackborne17aeb32011-04-07 15:11:57 -070010166 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
10167 ProcessRecord r = procs.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010168 if (r.thread != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010169 if (!isCheckinRequest && dumpAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010170 pw.println("\n** MEMINFO in pid " + r.pid + " [" + r.processName + "] **");
10171 pw.flush();
10172 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010173 Debug.MemoryInfo mi = null;
Dianne Hackbornb437e092011-08-05 17:50:29 -070010174 if (dumpAll) {
10175 try {
10176 mi = r.thread.dumpMemInfo(fd, isCheckinRequest, dumpAll, innerArgs);
10177 } catch (RemoteException e) {
10178 if (!isCheckinRequest) {
10179 pw.println("Got RemoteException!");
10180 pw.flush();
10181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010182 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010183 } else {
10184 mi = new Debug.MemoryInfo();
10185 Debug.getMemoryInfo(r.pid, mi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010186 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010187
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010188 if (!isCheckinRequest && mi != null) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010189 long myTotalPss = mi.getTotalPss();
10190 totalPss += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010191 MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")",
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010192 r.processName, myTotalPss, 0);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010193 procMems.add(pssItem);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010194
10195 nativePss += mi.nativePss;
10196 dalvikPss += mi.dalvikPss;
10197 otherPss += mi.otherPss;
10198 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
10199 long mem = mi.getOtherPss(j);
10200 miscPss[j] += mem;
10201 otherPss -= mem;
10202 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010203
10204 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010205 if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
10206 || oomIndex == (oomPss.length-1)) {
Dianne Hackbornb437e092011-08-05 17:50:29 -070010207 oomPss[oomIndex] += myTotalPss;
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010208 if (oomProcs[oomIndex] == null) {
10209 oomProcs[oomIndex] = new ArrayList<MemItem>();
10210 }
10211 oomProcs[oomIndex].add(pssItem);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010212 break;
10213 }
10214 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010215 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010216 }
10217 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010218
10219 if (!isCheckinRequest && procs.size() > 1) {
10220 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
10221
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010222 catMems.add(new MemItem("Native", "Native", nativePss, -1));
10223 catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2));
10224 catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010225 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010226 String label = Debug.MemoryInfo.getOtherLabel(j);
10227 catMems.add(new MemItem(label, label, miscPss[j], j));
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010228 }
10229
Dianne Hackbornb437e092011-08-05 17:50:29 -070010230 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
10231 for (int j=0; j<oomPss.length; j++) {
10232 if (oomPss[j] != 0) {
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010233 String label = DUMP_MEM_OOM_LABEL[j];
10234 MemItem item = new MemItem(label, label, oomPss[j],
10235 DUMP_MEM_OOM_ADJ[j]);
Dianne Hackborna4bacb82011-08-24 15:12:38 -070010236 item.subitems = oomProcs[j];
10237 oomMems.add(item);
Dianne Hackbornb437e092011-08-05 17:50:29 -070010238 }
10239 }
10240
Dianne Hackborn672342c2011-11-29 11:29:02 -080010241 if (outTag != null || outStack != null) {
10242 if (outTag != null) {
10243 appendMemBucket(outTag, totalPss, "total", false);
10244 }
10245 if (outStack != null) {
10246 appendMemBucket(outStack, totalPss, "total", true);
10247 }
10248 boolean firstLine = true;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010249 for (int i=0; i<oomMems.size(); i++) {
10250 MemItem miCat = oomMems.get(i);
10251 if (miCat.subitems == null || miCat.subitems.size() < 1) {
10252 continue;
10253 }
10254 if (miCat.id < ProcessList.SERVICE_ADJ
10255 || miCat.id == ProcessList.HOME_APP_ADJ
10256 || miCat.id == ProcessList.PREVIOUS_APP_ADJ) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010257 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10258 outTag.append(" / ");
10259 }
10260 if (outStack != null) {
10261 if (miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10262 if (firstLine) {
10263 outStack.append(":");
10264 firstLine = false;
10265 }
10266 outStack.append("\n\t at ");
10267 } else {
10268 outStack.append("$");
10269 }
10270 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010271 for (int j=0; j<miCat.subitems.size(); j++) {
10272 MemItem mi = miCat.subitems.get(j);
10273 if (j > 0) {
Dianne Hackborn672342c2011-11-29 11:29:02 -080010274 if (outTag != null) {
10275 outTag.append(" ");
10276 }
10277 if (outStack != null) {
10278 outStack.append("$");
10279 }
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010280 }
Dianne Hackborn672342c2011-11-29 11:29:02 -080010281 if (outTag != null && miCat.id <= ProcessList.FOREGROUND_APP_ADJ) {
10282 appendMemBucket(outTag, mi.pss, mi.shortLabel, false);
10283 }
10284 if (outStack != null) {
10285 appendMemBucket(outStack, mi.pss, mi.shortLabel, true);
10286 }
10287 }
10288 if (outStack != null && miCat.id >= ProcessList.FOREGROUND_APP_ADJ) {
10289 outStack.append("(");
10290 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
10291 if (DUMP_MEM_OOM_ADJ[k] == miCat.id) {
10292 outStack.append(DUMP_MEM_OOM_LABEL[k]);
10293 outStack.append(":");
10294 outStack.append(DUMP_MEM_OOM_ADJ[k]);
10295 }
10296 }
10297 outStack.append(")");
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010298 }
10299 }
10300 }
10301 }
10302
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010303 if (!brief && !oomOnly) {
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010304 pw.println();
10305 pw.println("Total PSS by process:");
10306 dumpMemItems(pw, " ", procMems, true);
10307 pw.println();
10308 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010309 pw.println("Total PSS by OOM adjustment:");
10310 dumpMemItems(pw, " ", oomMems, false);
Dianne Hackborne4d4fbc2011-11-08 11:53:28 -080010311 if (!oomOnly) {
10312 PrintWriter out = categoryPw != null ? categoryPw : pw;
10313 out.println();
10314 out.println("Total PSS by category:");
10315 dumpMemItems(out, " ", catMems, true);
Dianne Hackborn04d6db32011-11-04 20:07:24 -070010316 }
Dianne Hackbornb437e092011-08-05 17:50:29 -070010317 pw.println();
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080010318 pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB");
Dianne Hackbornd3e677b2012-04-05 14:58:18 -070010319 final int[] SINGLE_LONG_FORMAT = new int[] {
10320 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
10321 };
10322 long[] longOut = new long[1];
10323 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
10324 SINGLE_LONG_FORMAT, null, longOut, null);
10325 long shared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10326 longOut[0] = 0;
10327 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
10328 SINGLE_LONG_FORMAT, null, longOut, null);
10329 long sharing = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10330 longOut[0] = 0;
10331 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
10332 SINGLE_LONG_FORMAT, null, longOut, null);
10333 long unshared = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10334 longOut[0] = 0;
10335 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
10336 SINGLE_LONG_FORMAT, null, longOut, null);
10337 long voltile = longOut[0] * ProcessList.PAGE_SIZE / 1024;
10338 pw.print(" KSM: "); pw.print(sharing); pw.print(" kB saved from shared ");
10339 pw.print(shared); pw.println(" kB");
10340 pw.print(" "); pw.print(unshared); pw.print(" kB unshared; ");
10341 pw.print(voltile); pw.println(" kB volatile");
Dianne Hackborn0e3328f2011-07-17 13:31:17 -070010342 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010343 }
10344
10345 /**
10346 * Searches array of arguments for the specified string
10347 * @param args array of argument strings
10348 * @param value value to search for
10349 * @return true if the value is contained in the array
10350 */
10351 private static boolean scanArgs(String[] args, String value) {
10352 if (args != null) {
10353 for (String arg : args) {
10354 if (value.equals(arg)) {
10355 return true;
10356 }
10357 }
10358 }
10359 return false;
10360 }
10361
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010362 private final boolean removeDyingProviderLocked(ProcessRecord proc,
10363 ContentProviderRecord cpr, boolean always) {
10364 final boolean inLaunching = mLaunchingProviders.contains(cpr);
10365
10366 if (!inLaunching || always) {
10367 synchronized (cpr) {
10368 cpr.launchingApp = null;
10369 cpr.notifyAll();
10370 }
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070010371 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010372 String names[] = cpr.info.authority.split(";");
10373 for (int j = 0; j < names.length; j++) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070010374 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010375 }
10376 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010377
10378 for (int i=0; i<cpr.connections.size(); i++) {
10379 ContentProviderConnection conn = cpr.connections.get(i);
10380 if (conn.waiting) {
10381 // If this connection is waiting for the provider, then we don't
10382 // need to mess with its process unless we are always removing
10383 // or for some reason the provider is not currently launching.
10384 if (inLaunching && !always) {
10385 continue;
10386 }
10387 }
10388 ProcessRecord capp = conn.client;
10389 conn.dead = true;
10390 if (conn.stableCount > 0) {
10391 if (!capp.persistent && capp.thread != null
10392 && capp.pid != 0
10393 && capp.pid != MY_PID) {
10394 Slog.i(TAG, "Kill " + capp.processName
10395 + " (pid " + capp.pid + "): provider " + cpr.info.name
10396 + " in dying process " + (proc != null ? proc.processName : "??"));
10397 EventLog.writeEvent(EventLogTags.AM_KILL, capp.pid,
10398 capp.processName, capp.setAdj, "dying provider "
10399 + cpr.name.toShortString());
10400 Process.killProcessQuiet(capp.pid);
10401 }
10402 } else if (capp.thread != null && conn.provider.provider != null) {
10403 try {
10404 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
10405 } catch (RemoteException e) {
10406 }
10407 // In the protocol here, we don't expect the client to correctly
10408 // clean up this connection, we'll just remove it.
10409 cpr.connections.remove(i);
10410 conn.client.conProviders.remove(conn);
10411 }
10412 }
10413
10414 if (inLaunching && always) {
10415 mLaunchingProviders.remove(cpr);
10416 }
10417 return inLaunching;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010418 }
10419
10420 /**
10421 * Main code for cleaning up a process when it has gone away. This is
10422 * called both as a result of the process dying, or directly when stopping
10423 * a process when running in single process mode.
10424 */
10425 private final void cleanUpApplicationRecordLocked(ProcessRecord app,
Dianne Hackborn130b0d22011-07-26 22:07:48 -070010426 boolean restarting, boolean allowRestart, int index) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010427 if (index >= 0) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080010428 mLruProcesses.remove(index);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010429 }
10430
Dianne Hackborn36124872009-10-08 16:22:03 -070010431 mProcessesToGc.remove(app);
10432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010433 // Dismiss any open dialogs.
10434 if (app.crashDialog != null) {
10435 app.crashDialog.dismiss();
10436 app.crashDialog = null;
10437 }
10438 if (app.anrDialog != null) {
10439 app.anrDialog.dismiss();
10440 app.anrDialog = null;
10441 }
10442 if (app.waitDialog != null) {
10443 app.waitDialog.dismiss();
10444 app.waitDialog = null;
10445 }
10446
10447 app.crashing = false;
10448 app.notResponding = false;
10449
10450 app.resetPackageList();
Dianne Hackborn1b64e0d2011-07-17 15:23:59 -070010451 app.unlinkDeathRecipient();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010452 app.thread = null;
10453 app.forcingToForeground = null;
10454 app.foregroundServices = false;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010455 app.foregroundActivities = false;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070010456 app.hasShownUi = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070010457 app.hasAboveClient = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010458
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010459 mServices.killServicesLocked(app, allowRestart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010460
10461 boolean restart = false;
10462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010463 // Remove published content providers.
10464 if (!app.pubProviders.isEmpty()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010465 Iterator<ContentProviderRecord> it = app.pubProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010466 while (it.hasNext()) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010467 ContentProviderRecord cpr = it.next();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010468
10469 final boolean always = app.bad || !allowRestart;
10470 if (removeDyingProviderLocked(app, cpr, always) || always) {
10471 // We left the provider in the launching list, need to
10472 // restart it.
10473 restart = true;
10474 }
10475
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010476 cpr.provider = null;
Dianne Hackborn2a6bcda2011-09-21 15:07:05 -070010477 cpr.proc = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010478 }
10479 app.pubProviders.clear();
10480 }
10481
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010482 // Take care of any launching providers waiting for this process.
10483 if (checkAppInLaunchingProvidersLocked(app, false)) {
10484 restart = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010485 }
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010487 // Unregister from connected content providers.
10488 if (!app.conProviders.isEmpty()) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010489 for (int i=0; i<app.conProviders.size(); i++) {
10490 ContentProviderConnection conn = app.conProviders.get(i);
10491 conn.provider.connections.remove(conn);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010492 }
10493 app.conProviders.clear();
10494 }
10495
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010496 // At this point there may be remaining entries in mLaunchingProviders
10497 // where we were the only one waiting, so they are no longer of use.
10498 // Look for these and clean up if found.
10499 // XXX Commented out for now. Trying to figure out a way to reproduce
10500 // the actual situation to identify what is actually going on.
10501 if (false) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010502 for (int i=0; i<mLaunchingProviders.size(); i++) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010503 ContentProviderRecord cpr = (ContentProviderRecord)
10504 mLaunchingProviders.get(i);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010505 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070010506 synchronized (cpr) {
10507 cpr.launchingApp = null;
10508 cpr.notifyAll();
10509 }
10510 }
10511 }
10512 }
10513
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010514 skipCurrentReceiverLocked(app);
10515
10516 // Unregister any receivers.
10517 if (app.receivers.size() > 0) {
10518 Iterator<ReceiverList> it = app.receivers.iterator();
10519 while (it.hasNext()) {
10520 removeReceiverLocked(it.next());
10521 }
10522 app.receivers.clear();
10523 }
10524
Christopher Tate181fafa2009-05-14 11:12:14 -070010525 // If the app is undergoing backup, tell the backup manager about it
10526 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010527 if (DEBUG_BACKUP) Slog.d(TAG, "App " + mBackupTarget.appInfo + " died during backup");
Christopher Tate181fafa2009-05-14 11:12:14 -070010528 try {
10529 IBackupManager bm = IBackupManager.Stub.asInterface(
10530 ServiceManager.getService(Context.BACKUP_SERVICE));
10531 bm.agentDisconnected(app.info.packageName);
10532 } catch (RemoteException e) {
10533 // can't happen; backup manager is local
10534 }
10535 }
10536
Dianne Hackborna93c2c12012-05-31 15:29:36 -070010537 for (int i = mPendingProcessChanges.size()-1; i>=0; i--) {
10538 ProcessChangeItem item = mPendingProcessChanges.get(i);
10539 if (item.pid == app.pid) {
10540 mPendingProcessChanges.remove(i);
10541 mAvailProcessChanges.add(item);
10542 }
10543 }
Jeff Sharkey287bd832011-05-28 19:36:26 -070010544 mHandler.obtainMessage(DISPATCH_PROCESS_DIED, app.pid, app.info.uid, null).sendToTarget();
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070010545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010546 // If the caller is restarting this app, then leave it in its
10547 // current lists and let the caller take care of it.
10548 if (restarting) {
10549 return;
10550 }
10551
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010552 if (!app.persistent || app.isolated) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010553 if (DEBUG_PROCESSES) Slog.v(TAG,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010554 "Removing non-persistent process during cleanup: " + app);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010555 mProcessNames.remove(app.processName, app.uid);
10556 mIsolatedProcesses.remove(app.uid);
Dianne Hackborn860755f2010-06-03 18:47:52 -070010557 if (mHeavyWeightProcess == app) {
Dianne Hackborn41203752012-08-31 14:05:51 -070010558 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
10559 mHeavyWeightProcess.userId, 0));
Dianne Hackborn860755f2010-06-03 18:47:52 -070010560 mHeavyWeightProcess = null;
Dianne Hackborn860755f2010-06-03 18:47:52 -070010561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010562 } else if (!app.removed) {
10563 // This app is persistent, so we need to keep its record around.
10564 // If it is not already on the pending app list, add it there
10565 // and start a new process for it.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010566 if (mPersistentStartingProcesses.indexOf(app) < 0) {
10567 mPersistentStartingProcesses.add(app);
10568 restart = true;
10569 }
10570 }
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070010571 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG,
10572 "Clean-up removing on hold: " + app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010573 mProcessesOnHold.remove(app);
10574
The Android Open Source Project4df24232009-03-05 14:34:35 -080010575 if (app == mHomeProcess) {
10576 mHomeProcess = null;
10577 }
Dianne Hackbornf35fe232011-11-01 19:25:20 -070010578 if (app == mPreviousProcess) {
10579 mPreviousProcess = null;
10580 }
10581
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010582 if (restart && !app.isolated) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010583 // We have components that still need to be running in the
10584 // process, so re-launch it.
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010585 mProcessNames.put(app.processName, app.uid, app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010586 startProcessLocked(app, "restart", app.processName);
10587 } else if (app.pid > 0 && app.pid != MY_PID) {
10588 // Goodbye!
10589 synchronized (mPidsSelfLocked) {
10590 mPidsSelfLocked.remove(app.pid);
10591 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
10592 }
Dianne Hackbornf210d6b2009-04-13 18:42:49 -070010593 app.setPid(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010594 }
10595 }
10596
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010597 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
10598 // Look through the content providers we are waiting to have launched,
10599 // and if any run in this process then either schedule a restart of
10600 // the process or kill the client waiting for it if this process has
10601 // gone bad.
10602 int NL = mLaunchingProviders.size();
10603 boolean restart = false;
10604 for (int i=0; i<NL; i++) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070010605 ContentProviderRecord cpr = mLaunchingProviders.get(i);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010606 if (cpr.launchingApp == app) {
10607 if (!alwaysBad && !app.bad) {
10608 restart = true;
10609 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070010610 removeDyingProviderLocked(app, cpr, true);
Dianne Hackbornf670ef72009-11-16 13:59:16 -080010611 NL = mLaunchingProviders.size();
10612 }
10613 }
10614 }
10615 return restart;
10616 }
10617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010618 // =========================================================
10619 // SERVICES
10620 // =========================================================
10621
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010622 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
10623 int flags) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010624 enforceNotIsolatedCaller("getServices");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010625 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010626 return mServices.getRunningServiceInfoLocked(maxNum, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010627 }
10628 }
10629
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010630 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010631 enforceNotIsolatedCaller("getRunningServiceControlPanel");
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010632 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010633 return mServices.getRunningServiceControlPanelLocked(name);
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010634 }
Dianne Hackborndd9b82c2009-09-03 00:18:47 -070010635 }
10636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010637 public ComponentName startService(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010638 String resolvedType, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010639 enforceNotIsolatedCaller("startService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010640 // Refuse possible leaked file descriptors
10641 if (service != null && service.hasFileDescriptors() == true) {
10642 throw new IllegalArgumentException("File descriptors passed in Intent");
10643 }
10644
Amith Yamasani742a6712011-05-04 14:49:28 -070010645 if (DEBUG_SERVICE)
10646 Slog.v(TAG, "startService: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010647 synchronized(this) {
10648 final int callingPid = Binder.getCallingPid();
10649 final int callingUid = Binder.getCallingUid();
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010650 checkValidCaller(callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010651 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010652 ComponentName res = mServices.startServiceLocked(caller, service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010653 resolvedType, callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010654 Binder.restoreCallingIdentity(origId);
10655 return res;
10656 }
10657 }
10658
10659 ComponentName startServiceInPackage(int uid,
Dianne Hackborn41203752012-08-31 14:05:51 -070010660 Intent service, String resolvedType, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010661 synchronized(this) {
Amith Yamasani742a6712011-05-04 14:49:28 -070010662 if (DEBUG_SERVICE)
10663 Slog.v(TAG, "startServiceInPackage: " + service + " type=" + resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010664 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010665 ComponentName res = mServices.startServiceLocked(null, service,
Dianne Hackborn41203752012-08-31 14:05:51 -070010666 resolvedType, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010667 Binder.restoreCallingIdentity(origId);
10668 return res;
10669 }
10670 }
10671
10672 public int stopService(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010673 String resolvedType, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010674 enforceNotIsolatedCaller("stopService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010675 // Refuse possible leaked file descriptors
10676 if (service != null && service.hasFileDescriptors() == true) {
10677 throw new IllegalArgumentException("File descriptors passed in Intent");
10678 }
10679
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010680 checkValidCaller(Binder.getCallingUid(), userId);
10681
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010682 synchronized(this) {
Dianne Hackborn7767eac2012-08-23 18:25:40 -070010683 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010684 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010685 }
10686
10687 public IBinder peekService(Intent service, String resolvedType) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010688 enforceNotIsolatedCaller("peekService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010689 // Refuse possible leaked file descriptors
10690 if (service != null && service.hasFileDescriptors() == true) {
10691 throw new IllegalArgumentException("File descriptors passed in Intent");
10692 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010693 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010694 return mServices.peekServiceLocked(service, resolvedType);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010695 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010696 }
10697
10698 public boolean stopServiceToken(ComponentName className, IBinder token,
10699 int startId) {
10700 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010701 return mServices.stopServiceTokenLocked(className, token, startId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010702 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010703 }
10704
10705 public void setServiceForeground(ComponentName className, IBinder token,
Dianne Hackbornd8a43f62009-08-17 23:33:56 -070010706 int id, Notification notification, boolean removeNotification) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010707 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010708 mServices.setServiceForegroundLocked(className, token, id, notification,
10709 removeNotification);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010710 }
10711 }
Amith Yamasania4a54e22012-04-16 15:44:19 -070010712
Dianne Hackborn41203752012-08-31 14:05:51 -070010713 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
10714 boolean requireFull, String name, String callerPackage) {
10715 synchronized(this) {
10716 return handleIncomingUserLocked(callingPid, callingUid, userId, allowAll,
10717 requireFull, name, callerPackage);
10718 }
10719 }
10720
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070010721 int handleIncomingUserLocked(int callingPid, int callingUid, int userId, boolean allowAll,
10722 boolean requireFull, String name, String callerPackage) {
10723 final int callingUserId = UserHandle.getUserId(callingUid);
10724 if (callingUserId != userId) {
10725 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10726 if ((requireFull || checkComponentPermission(
10727 android.Manifest.permission.INTERACT_ACROSS_USERS,
10728 callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED)
10729 && checkComponentPermission(
10730 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
10731 callingPid, callingUid, -1, true)
10732 != PackageManager.PERMISSION_GRANTED) {
10733 if (userId == UserHandle.USER_CURRENT_OR_SELF) {
10734 // In this case, they would like to just execute as their
10735 // owner user instead of failing.
10736 userId = callingUserId;
10737 } else {
Dianne Hackborn41203752012-08-31 14:05:51 -070010738 StringBuilder builder = new StringBuilder(128);
10739 builder.append("Permission Denial: ");
10740 builder.append(name);
10741 if (callerPackage != null) {
10742 builder.append(" from ");
10743 builder.append(callerPackage);
10744 }
10745 builder.append(" asks to run as user ");
10746 builder.append(userId);
10747 builder.append(" but is calling from user ");
10748 builder.append(UserHandle.getUserId(callingUid));
10749 builder.append("; this requires ");
10750 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL);
10751 if (!requireFull) {
10752 builder.append("or");
10753 builder.append(android.Manifest.permission.INTERACT_ACROSS_USERS);
10754 }
10755 String msg = builder.toString();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070010756 Slog.w(TAG, msg);
10757 throw new SecurityException(msg);
10758 }
10759 }
10760 }
10761 if (userId == UserHandle.USER_CURRENT
10762 || userId == UserHandle.USER_CURRENT_OR_SELF) {
10763 userId = mCurrentUserId;
10764 }
10765 if (!allowAll && userId < 0) {
10766 throw new IllegalArgumentException(
10767 "Call does not support special user #" + userId);
10768 }
10769 }
10770 return userId;
10771 }
10772
Dianne Hackborn7d19e022012-08-07 19:12:33 -070010773 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
10774 String className, int flags) {
Amith Yamasania4a54e22012-04-16 15:44:19 -070010775 boolean result = false;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070010776 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -070010777 if ((flags&ServiceInfo.FLAG_SINGLE_USER) != 0) {
10778 if (ActivityManager.checkUidPermission(
10779 android.Manifest.permission.INTERACT_ACROSS_USERS,
10780 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
10781 ComponentName comp = new ComponentName(aInfo.packageName, className);
10782 String msg = "Permission Denial: Component " + comp.flattenToShortString()
10783 + " requests FLAG_SINGLE_USER, but app does not hold "
10784 + android.Manifest.permission.INTERACT_ACROSS_USERS;
10785 Slog.w(TAG, msg);
10786 throw new SecurityException(msg);
10787 }
10788 result = true;
10789 }
Amith Yamasania4a54e22012-04-16 15:44:19 -070010790 } else if (componentProcessName == aInfo.packageName) {
10791 result = (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
10792 } else if ("system".equals(componentProcessName)) {
10793 result = true;
10794 }
10795 if (DEBUG_MU) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -070010796 Slog.v(TAG, "isSingleton(" + componentProcessName + ", " + aInfo
10797 + ", " + className + ", 0x" + Integer.toHexString(flags) + ") = " + result);
Amith Yamasania4a54e22012-04-16 15:44:19 -070010798 }
10799 return result;
10800 }
10801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010802 public int bindService(IApplicationThread caller, IBinder token,
10803 Intent service, String resolvedType,
Amith Yamasani37ce3a82012-02-06 12:04:42 -080010804 IServiceConnection connection, int flags, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080010805 enforceNotIsolatedCaller("bindService");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010806 // Refuse possible leaked file descriptors
10807 if (service != null && service.hasFileDescriptors() == true) {
10808 throw new IllegalArgumentException("File descriptors passed in Intent");
10809 }
10810
10811 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010812 return mServices.bindServiceLocked(caller, token, service, resolvedType,
10813 connection, flags, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010814 }
10815 }
10816
10817 public boolean unbindService(IServiceConnection connection) {
10818 synchronized (this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010819 return mServices.unbindServiceLocked(connection);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010820 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010821 }
10822
10823 public void publishService(IBinder token, Intent intent, IBinder service) {
10824 // Refuse possible leaked file descriptors
10825 if (intent != null && intent.hasFileDescriptors() == true) {
10826 throw new IllegalArgumentException("File descriptors passed in Intent");
10827 }
10828
10829 synchronized(this) {
10830 if (!(token instanceof ServiceRecord)) {
10831 throw new IllegalArgumentException("Invalid service token");
10832 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010833 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010834 }
10835 }
10836
10837 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
10838 // Refuse possible leaked file descriptors
10839 if (intent != null && intent.hasFileDescriptors() == true) {
10840 throw new IllegalArgumentException("File descriptors passed in Intent");
10841 }
10842
10843 synchronized(this) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010844 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010845 }
10846 }
10847
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -070010848 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010849 synchronized(this) {
10850 if (!(token instanceof ServiceRecord)) {
10851 throw new IllegalArgumentException("Invalid service token");
10852 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -070010853 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070010854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010855 }
10856
10857 // =========================================================
Christopher Tate181fafa2009-05-14 11:12:14 -070010858 // BACKUP AND RESTORE
10859 // =========================================================
10860
10861 // Cause the target app to be launched if necessary and its backup agent
10862 // instantiated. The backup agent will invoke backupAgentCreated() on the
10863 // activity manager to announce its creation.
10864 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010865 if (DEBUG_BACKUP) Slog.v(TAG, "startBackupAgent: app=" + app + " mode=" + backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010866 enforceCallingPermission("android.permission.BACKUP", "startBackupAgent");
10867
10868 synchronized(this) {
10869 // !!! TODO: currently no check here that we're already bound
10870 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
10871 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
10872 synchronized (stats) {
10873 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
10874 }
10875
Dianne Hackborne7f97212011-02-24 14:40:20 -080010876 // Backup agent is now in use, its package can't be stopped.
10877 try {
10878 AppGlobals.getPackageManager().setPackageStoppedState(
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070010879 app.packageName, false, UserHandle.getUserId(app.uid));
Dianne Hackborne7f97212011-02-24 14:40:20 -080010880 } catch (RemoteException e) {
Dianne Hackborna925cd42011-03-10 13:18:20 -080010881 } catch (IllegalArgumentException e) {
10882 Slog.w(TAG, "Failed trying to unstop package "
10883 + app.packageName + ": " + e);
Dianne Hackborne7f97212011-02-24 14:40:20 -080010884 }
10885
Christopher Tate181fafa2009-05-14 11:12:14 -070010886 BackupRecord r = new BackupRecord(ss, app, backupMode);
Christopher Tate4a627c72011-04-01 14:43:32 -070010887 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
10888 ? new ComponentName(app.packageName, app.backupAgentName)
10889 : new ComponentName("android", "FullBackupAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -070010890 // startProcessLocked() returns existing proc's record if it's already running
10891 ProcessRecord proc = startProcessLocked(app.processName, app,
Dianne Hackborna0c283e2012-02-09 10:47:01 -080010892 false, 0, "backup", hostingName, false, false);
Christopher Tate181fafa2009-05-14 11:12:14 -070010893 if (proc == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010894 Slog.e(TAG, "Unable to start backup agent process " + r);
Christopher Tate181fafa2009-05-14 11:12:14 -070010895 return false;
10896 }
10897
10898 r.app = proc;
10899 mBackupTarget = r;
10900 mBackupAppName = app.packageName;
10901
Christopher Tate6fa95972009-06-05 18:43:55 -070010902 // Try not to kill the process during backup
10903 updateOomAdjLocked(proc);
10904
Christopher Tate181fafa2009-05-14 11:12:14 -070010905 // If the process is already attached, schedule the creation of the backup agent now.
10906 // If it is not yet live, this will be done when it attaches to the framework.
10907 if (proc.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010908 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc already running: " + proc);
Christopher Tate181fafa2009-05-14 11:12:14 -070010909 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010910 proc.thread.scheduleCreateBackupAgent(app,
10911 compatibilityInfoForPackageLocked(app), backupMode);
Christopher Tate181fafa2009-05-14 11:12:14 -070010912 } catch (RemoteException e) {
Christopher Tate436344a2009-09-30 16:17:37 -070010913 // Will time out on the backup manager side
Christopher Tate181fafa2009-05-14 11:12:14 -070010914 }
10915 } else {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010916 if (DEBUG_BACKUP) Slog.v(TAG, "Agent proc not running, waiting for attach");
Christopher Tate181fafa2009-05-14 11:12:14 -070010917 }
10918 // Invariants: at this point, the target app process exists and the application
10919 // is either already running or in the process of coming up. mBackupTarget and
10920 // mBackupAppName describe the app, so that when it binds back to the AM we
10921 // know that it's scheduled for a backup-agent operation.
10922 }
10923
10924 return true;
10925 }
10926
10927 // A backup agent has just come up
10928 public void backupAgentCreated(String agentPackageName, IBinder agent) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010929 if (DEBUG_BACKUP) Slog.v(TAG, "backupAgentCreated: " + agentPackageName
Christopher Tate181fafa2009-05-14 11:12:14 -070010930 + " = " + agent);
10931
10932 synchronized(this) {
10933 if (!agentPackageName.equals(mBackupAppName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010934 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
Christopher Tate181fafa2009-05-14 11:12:14 -070010935 return;
10936 }
Dianne Hackborn06740692010-09-22 22:46:21 -070010937 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010938
Dianne Hackborn06740692010-09-22 22:46:21 -070010939 long oldIdent = Binder.clearCallingIdentity();
10940 try {
10941 IBackupManager bm = IBackupManager.Stub.asInterface(
10942 ServiceManager.getService(Context.BACKUP_SERVICE));
10943 bm.agentConnected(agentPackageName, agent);
10944 } catch (RemoteException e) {
10945 // can't happen; the backup manager service is local
10946 } catch (Exception e) {
10947 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
10948 e.printStackTrace();
10949 } finally {
10950 Binder.restoreCallingIdentity(oldIdent);
Christopher Tate181fafa2009-05-14 11:12:14 -070010951 }
10952 }
10953
10954 // done with this agent
10955 public void unbindBackupAgent(ApplicationInfo appInfo) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010956 if (DEBUG_BACKUP) Slog.v(TAG, "unbindBackupAgent: " + appInfo);
Christopher Tate8a27f922009-06-26 11:49:18 -070010957 if (appInfo == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010958 Slog.w(TAG, "unbind backup agent for null app");
Christopher Tate8a27f922009-06-26 11:49:18 -070010959 return;
10960 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010961
10962 synchronized(this) {
Christopher Tate8a27f922009-06-26 11:49:18 -070010963 if (mBackupAppName == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010964 Slog.w(TAG, "Unbinding backup agent with no active backup");
Christopher Tate8a27f922009-06-26 11:49:18 -070010965 return;
10966 }
10967
Christopher Tate181fafa2009-05-14 11:12:14 -070010968 if (!mBackupAppName.equals(appInfo.packageName)) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010969 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
Christopher Tate181fafa2009-05-14 11:12:14 -070010970 return;
10971 }
10972
Christopher Tate6fa95972009-06-05 18:43:55 -070010973 ProcessRecord proc = mBackupTarget.app;
10974 mBackupTarget = null;
10975 mBackupAppName = null;
10976
10977 // Not backing this app up any more; reset its OOM adjustment
10978 updateOomAdjLocked(proc);
10979
Christopher Tatec7b31e32009-06-10 15:49:30 -070010980 // If the app crashed during backup, 'thread' will be null here
10981 if (proc.thread != null) {
10982 try {
Dianne Hackborne2515ee2011-04-27 18:52:56 -040010983 proc.thread.scheduleDestroyBackupAgent(appInfo,
10984 compatibilityInfoForPackageLocked(appInfo));
Christopher Tatec7b31e32009-06-10 15:49:30 -070010985 } catch (Exception e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080010986 Slog.e(TAG, "Exception when unbinding backup agent:");
Christopher Tatec7b31e32009-06-10 15:49:30 -070010987 e.printStackTrace();
10988 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010989 }
Christopher Tate181fafa2009-05-14 11:12:14 -070010990 }
10991 }
10992 // =========================================================
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010993 // BROADCASTS
10994 // =========================================================
10995
Josh Bartel7f208742010-02-25 11:01:44 -060010996 private final List getStickiesLocked(String action, IntentFilter filter,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070010997 List cur, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010998 final ContentResolver resolver = mContext.getContentResolver();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070010999 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11000 if (stickies == null) {
11001 return cur;
11002 }
11003 final ArrayList<Intent> list = stickies.get(action);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011004 if (list == null) {
11005 return cur;
11006 }
11007 int N = list.size();
11008 for (int i=0; i<N; i++) {
11009 Intent intent = list.get(i);
11010 if (filter.match(resolver, intent, true, TAG) >= 0) {
11011 if (cur == null) {
11012 cur = new ArrayList<Intent>();
11013 }
11014 cur.add(intent);
11015 }
11016 }
11017 return cur;
11018 }
11019
Christopher Tatef46723b2012-01-26 14:19:24 -080011020 boolean isPendingBroadcastProcessLocked(int pid) {
11021 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
11022 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
11023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011024
Christopher Tatef46723b2012-01-26 14:19:24 -080011025 void skipPendingBroadcastLocked(int pid) {
11026 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
11027 for (BroadcastQueue queue : mBroadcastQueues) {
11028 queue.skipPendingBroadcastLocked(pid);
11029 }
11030 }
11031
11032 // The app just attached; send any pending broadcasts that it should receive
11033 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
11034 boolean didSomething = false;
11035 for (BroadcastQueue queue : mBroadcastQueues) {
11036 didSomething |= queue.sendPendingBroadcastsLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011037 }
Christopher Tatef46723b2012-01-26 14:19:24 -080011038 return didSomething;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011039 }
11040
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011041 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
Dianne Hackborn20e80982012-08-31 19:00:44 -070011042 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011043 enforceNotIsolatedCaller("registerReceiver");
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011044 int callingUid;
Dianne Hackborn20e80982012-08-31 19:00:44 -070011045 int callingPid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011046 synchronized(this) {
11047 ProcessRecord callerApp = null;
11048 if (caller != null) {
11049 callerApp = getRecordForAppLocked(caller);
11050 if (callerApp == null) {
11051 throw new SecurityException(
11052 "Unable to find app for caller " + caller
11053 + " (pid=" + Binder.getCallingPid()
11054 + ") when registering receiver " + receiver);
11055 }
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011056 if (callerApp.info.uid != Process.SYSTEM_UID &&
11057 !callerApp.pkgList.contains(callerPackage)) {
11058 throw new SecurityException("Given caller package " + callerPackage
11059 + " is not running in process " + callerApp);
11060 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011061 callingUid = callerApp.info.uid;
Dianne Hackborn20e80982012-08-31 19:00:44 -070011062 callingPid = callerApp.pid;
Dianne Hackborn6c418d52011-06-29 14:05:33 -070011063 } else {
11064 callerPackage = null;
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011065 callingUid = Binder.getCallingUid();
Dianne Hackborn20e80982012-08-31 19:00:44 -070011066 callingPid = Binder.getCallingPid();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011067 }
11068
Dianne Hackborn20e80982012-08-31 19:00:44 -070011069 userId = this.handleIncomingUserLocked(callingPid, callingUid, userId,
11070 true, true, "registerReceiver", callerPackage);
11071
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011072 List allSticky = null;
11073
11074 // Look for any matching sticky broadcasts...
11075 Iterator actions = filter.actionsIterator();
11076 if (actions != null) {
11077 while (actions.hasNext()) {
11078 String action = (String)actions.next();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011079 allSticky = getStickiesLocked(action, filter, allSticky,
11080 UserHandle.USER_ALL);
11081 allSticky = getStickiesLocked(action, filter, allSticky,
11082 UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011083 }
11084 } else {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011085 allSticky = getStickiesLocked(null, filter, allSticky,
11086 UserHandle.USER_ALL);
11087 allSticky = getStickiesLocked(null, filter, allSticky,
11088 UserHandle.getUserId(callingUid));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011089 }
11090
11091 // The first sticky in the list is returned directly back to
11092 // the client.
11093 Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
11094
Joe Onorato8a9b2202010-02-26 18:56:32 -080011095 if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011096 + ": " + sticky);
11097
11098 if (receiver == null) {
11099 return sticky;
11100 }
11101
11102 ReceiverList rl
11103 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
11104 if (rl == null) {
Dianne Hackborn20e80982012-08-31 19:00:44 -070011105 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
11106 userId, receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011107 if (rl.app != null) {
11108 rl.app.receivers.add(rl);
11109 } else {
11110 try {
11111 receiver.asBinder().linkToDeath(rl, 0);
11112 } catch (RemoteException e) {
11113 return sticky;
11114 }
11115 rl.linkedToDeath = true;
11116 }
11117 mRegisteredReceivers.put(receiver.asBinder(), rl);
Dianne Hackborn20e80982012-08-31 19:00:44 -070011118 } else if (rl.uid != callingUid) {
11119 throw new IllegalArgumentException(
11120 "Receiver requested to register for uid " + callingUid
11121 + " was previously registered for uid " + rl.uid);
11122 } else if (rl.pid != callingPid) {
11123 throw new IllegalArgumentException(
11124 "Receiver requested to register for pid " + callingPid
11125 + " was previously registered for pid " + rl.pid);
11126 } else if (rl.userId != userId) {
11127 throw new IllegalArgumentException(
11128 "Receiver requested to register for user " + userId
11129 + " was previously registered for user " + rl.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011130 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011131 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
Dianne Hackborn20e80982012-08-31 19:00:44 -070011132 permission, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011133 rl.add(bf);
11134 if (!bf.debugCheck()) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011135 Slog.w(TAG, "==> For Dynamic broadast");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011136 }
11137 mReceiverResolver.addFilter(bf);
11138
11139 // Enqueue broadcasts for all existing stickies that match
11140 // this filter.
11141 if (allSticky != null) {
11142 ArrayList receivers = new ArrayList();
11143 receivers.add(bf);
11144
11145 int N = allSticky.size();
11146 for (int i=0; i<N; i++) {
11147 Intent intent = (Intent)allSticky.get(i);
Christopher Tatef46723b2012-01-26 14:19:24 -080011148 BroadcastQueue queue = broadcastQueueForIntent(intent);
11149 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011150 null, -1, -1, null, receivers, null, 0, null, null,
Amith Yamasani8bf06ed2012-08-27 19:30:30 -070011151 false, true, true, -1);
Christopher Tatef46723b2012-01-26 14:19:24 -080011152 queue.enqueueParallelBroadcastLocked(r);
11153 queue.scheduleBroadcastsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011154 }
11155 }
11156
11157 return sticky;
11158 }
11159 }
11160
11161 public void unregisterReceiver(IIntentReceiver receiver) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011162 if (DEBUG_BROADCAST) Slog.v(TAG, "Unregister receiver: " + receiver);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011163
Christopher Tatef46723b2012-01-26 14:19:24 -080011164 final long origId = Binder.clearCallingIdentity();
11165 try {
11166 boolean doTrim = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011167
Christopher Tatef46723b2012-01-26 14:19:24 -080011168 synchronized(this) {
11169 ReceiverList rl
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011170 = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
Christopher Tatef46723b2012-01-26 14:19:24 -080011171 if (rl != null) {
11172 if (rl.curBroadcast != null) {
11173 BroadcastRecord r = rl.curBroadcast;
11174 final boolean doNext = finishReceiverLocked(
11175 receiver.asBinder(), r.resultCode, r.resultData,
11176 r.resultExtras, r.resultAbort, true);
11177 if (doNext) {
11178 doTrim = true;
11179 r.queue.processNextBroadcast(false);
11180 }
11181 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011182
Christopher Tatef46723b2012-01-26 14:19:24 -080011183 if (rl.app != null) {
11184 rl.app.receivers.remove(rl);
11185 }
11186 removeReceiverLocked(rl);
11187 if (rl.linkedToDeath) {
11188 rl.linkedToDeath = false;
11189 rl.receiver.asBinder().unlinkToDeath(rl, 0);
11190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011191 }
11192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011193
Christopher Tatef46723b2012-01-26 14:19:24 -080011194 // If we actually concluded any broadcasts, we might now be able
11195 // to trim the recipients' apps from our working set
11196 if (doTrim) {
11197 trimApplications();
11198 return;
11199 }
11200
11201 } finally {
11202 Binder.restoreCallingIdentity(origId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011203 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011204 }
11205
11206 void removeReceiverLocked(ReceiverList rl) {
11207 mRegisteredReceivers.remove(rl.receiver.asBinder());
11208 int N = rl.size();
11209 for (int i=0; i<N; i++) {
11210 mReceiverResolver.removeFilter(rl.get(i));
11211 }
11212 }
11213
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011214 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011215 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
11216 ProcessRecord r = mLruProcesses.get(i);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011217 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011218 try {
11219 r.thread.dispatchPackageBroadcast(cmd, packages);
11220 } catch (RemoteException ex) {
11221 }
11222 }
11223 }
11224 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011225
11226 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
11227 int[] users) {
11228 List<ResolveInfo> receivers = null;
11229 try {
11230 HashSet<ComponentName> singleUserReceivers = null;
11231 boolean scannedFirstReceivers = false;
11232 for (int user : users) {
11233 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
11234 .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);
11235 if (newReceivers != null && newReceivers.size() == 0) {
11236 newReceivers = null;
11237 }
11238 if (receivers == null) {
11239 receivers = newReceivers;
11240 } else if (newReceivers != null) {
11241 // We need to concatenate the additional receivers
11242 // found with what we have do far. This would be easy,
11243 // but we also need to de-dup any receivers that are
11244 // singleUser.
11245 if (!scannedFirstReceivers) {
11246 // Collect any single user receivers we had already retrieved.
11247 scannedFirstReceivers = true;
11248 for (int i=0; i<receivers.size(); i++) {
11249 ResolveInfo ri = receivers.get(i);
11250 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11251 ComponentName cn = new ComponentName(
11252 ri.activityInfo.packageName, ri.activityInfo.name);
11253 if (singleUserReceivers == null) {
11254 singleUserReceivers = new HashSet<ComponentName>();
11255 }
11256 singleUserReceivers.add(cn);
11257 }
11258 }
11259 }
11260 // Add the new results to the existing results, tracking
11261 // and de-dupping single user receivers.
11262 for (int i=0; i<newReceivers.size(); i++) {
11263 ResolveInfo ri = receivers.get(i);
11264 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
11265 ComponentName cn = new ComponentName(
11266 ri.activityInfo.packageName, ri.activityInfo.name);
11267 if (singleUserReceivers == null) {
11268 singleUserReceivers = new HashSet<ComponentName>();
11269 }
11270 if (!singleUserReceivers.contains(cn)) {
11271 singleUserReceivers.add(cn);
11272 receivers.add(ri);
11273 }
11274 } else {
11275 receivers.add(ri);
11276 }
11277 }
11278 }
11279 }
11280 } catch (RemoteException ex) {
11281 // pm is in same process, this will never happen.
11282 }
11283 return receivers;
11284 }
11285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011286 private final int broadcastIntentLocked(ProcessRecord callerApp,
11287 String callerPackage, Intent intent, String resolvedType,
11288 IIntentReceiver resultTo, int resultCode, String resultData,
11289 Bundle map, String requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070011290 boolean ordered, boolean sticky, int callingPid, int callingUid,
11291 int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011292 intent = new Intent(intent);
11293
Dianne Hackborne7f97212011-02-24 14:40:20 -080011294 // By default broadcasts do not go to stopped apps.
11295 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
11296
Joe Onorato8a9b2202010-02-26 18:56:32 -080011297 if (DEBUG_BROADCAST_LIGHT) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011298 TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
Amith Yamasani13593602012-03-22 16:16:17 -070011299 + " ordered=" + ordered + " userid=" + userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011300 if ((resultTo != null) && !ordered) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011301 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011302 }
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011303
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011304 userId = handleIncomingUserLocked(callingPid, callingUid, userId,
11305 true, false, "broadcast", callerPackage);
Dianne Hackbornb4163a62012-08-02 18:31:26 -070011306
Dianne Hackborn80a4af22012-08-27 19:18:31 -070011307 // Make sure that the user who is receiving this broadcast is started
11308 // If not, we will just skip it.
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011309 if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070011310 Slog.w(TAG, "Skipping broadcast of " + intent
11311 + ": user " + userId + " is stopped");
11312 return ActivityManager.BROADCAST_SUCCESS;
11313 }
11314
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011315 /*
11316 * Prevent non-system code (defined here to be non-persistent
11317 * processes) from sending protected broadcasts.
11318 */
11319 if (callingUid == Process.SYSTEM_UID || callingUid == Process.PHONE_UID
11320 || callingUid == Process.SHELL_UID || callingUid == Process.BLUETOOTH_UID ||
11321 callingUid == 0) {
11322 // Always okay.
11323 } else if (callerApp == null || !callerApp.persistent) {
11324 try {
11325 if (AppGlobals.getPackageManager().isProtectedBroadcast(
11326 intent.getAction())) {
11327 String msg = "Permission Denial: not allowed to send broadcast "
11328 + intent.getAction() + " from pid="
11329 + callingPid + ", uid=" + callingUid;
11330 Slog.w(TAG, msg);
11331 throw new SecurityException(msg);
11332 }
11333 } catch (RemoteException e) {
11334 Slog.w(TAG, "Remote exception", e);
11335 return ActivityManager.BROADCAST_SUCCESS;
11336 }
11337 }
11338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 // Handle special intents: if this broadcast is from the package
11340 // manager about a package being removed, we need to remove all of
11341 // its activities from the history stack.
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011342 final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011343 intent.getAction());
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011344 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
11345 || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011346 || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011347 || uidRemoved) {
11348 if (checkComponentPermission(
11349 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
Dianne Hackborn6c2c5fc2011-01-18 17:02:33 -080011350 callingPid, callingUid, -1, true)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011351 == PackageManager.PERMISSION_GRANTED) {
11352 if (uidRemoved) {
11353 final Bundle intentExtras = intent.getExtras();
11354 final int uid = intentExtras != null
11355 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
11356 if (uid >= 0) {
11357 BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
11358 synchronized (bs) {
11359 bs.removeUidStatsLocked(uid);
11360 }
11361 }
11362 } else {
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011363 // If resources are unavailable just force stop all
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011364 // those packages and flush the attribute cache as well.
Suchi Amalapurapub56ae202010-02-04 22:51:07 -080011365 if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011366 String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
11367 if (list != null && (list.length > 0)) {
11368 for (String pkg : list) {
Amith Yamasani483f3b02012-03-13 16:08:00 -070011369 forceStopPackageLocked(pkg, -1, false, true, true, false, userId);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011370 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011371 sendPackageBroadcastLocked(
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011372 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011373 }
11374 } else {
11375 Uri data = intent.getData();
11376 String ssp;
11377 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11378 if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
11379 forceStopPackageLocked(ssp,
Amith Yamasani483f3b02012-03-13 16:08:00 -070011380 intent.getIntExtra(Intent.EXTRA_UID, -1), false, true, true,
11381 false, userId);
Dianne Hackbornde7faf62009-06-30 13:27:30 -070011382 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011383 if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011384 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011385 new String[] {ssp}, userId);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -070011386 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011387 }
11388 }
11389 }
11390 } else {
11391 String msg = "Permission Denial: " + intent.getAction()
11392 + " broadcast from " + callerPackage + " (pid=" + callingPid
11393 + ", uid=" + callingUid + ")"
11394 + " requires "
11395 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011396 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011397 throw new SecurityException(msg);
11398 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011399
11400 // Special case for adding a package: by default turn on compatibility
11401 // mode.
11402 } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
Dianne Hackborn8ea5e1d2011-05-27 16:45:31 -070011403 Uri data = intent.getData();
11404 String ssp;
11405 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
11406 mCompatModePackages.handlePackageAddedLocked(ssp,
11407 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011409 }
11410
11411 /*
11412 * If this is the time zone changed action, queue up a message that will reset the timezone
11413 * of all currently running processes. This message will get queued up before the broadcast
11414 * happens.
11415 */
11416 if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
11417 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
11418 }
11419
Robert Greenwalt03595d02010-11-02 14:08:23 -070011420 if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
11421 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE);
11422 }
11423
Robert Greenwalt434203a2010-10-11 16:00:27 -070011424 if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
11425 ProxyProperties proxy = intent.getParcelableExtra("proxy");
11426 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY, proxy));
11427 }
11428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011429 // Add to the sticky list if requested.
11430 if (sticky) {
11431 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
11432 callingPid, callingUid)
11433 != PackageManager.PERMISSION_GRANTED) {
11434 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
11435 + callingPid + ", uid=" + callingUid
11436 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011437 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011438 throw new SecurityException(msg);
11439 }
11440 if (requiredPermission != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011441 Slog.w(TAG, "Can't broadcast sticky intent " + intent
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011442 + " and enforce permission " + requiredPermission);
Dianne Hackborna4972e92012-03-14 10:38:05 -070011443 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011444 }
11445 if (intent.getComponent() != null) {
11446 throw new SecurityException(
11447 "Sticky broadcasts can't target a specific component");
11448 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011449 // We use userId directly here, since the "all" target is maintained
11450 // as a separate set of sticky broadcasts.
11451 if (userId != UserHandle.USER_ALL) {
11452 // But first, if this is not a broadcast to all users, then
11453 // make sure it doesn't conflict with an existing broadcast to
11454 // all users.
11455 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
11456 UserHandle.USER_ALL);
11457 if (stickies != null) {
11458 ArrayList<Intent> list = stickies.get(intent.getAction());
11459 if (list != null) {
11460 int N = list.size();
11461 int i;
11462 for (i=0; i<N; i++) {
11463 if (intent.filterEquals(list.get(i))) {
11464 throw new IllegalArgumentException(
11465 "Sticky broadcast " + intent + " for user "
11466 + userId + " conflicts with existing global broadcast");
11467 }
11468 }
11469 }
11470 }
11471 }
11472 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11473 if (stickies == null) {
11474 stickies = new HashMap<String, ArrayList<Intent>>();
11475 mStickyBroadcasts.put(userId, stickies);
11476 }
11477 ArrayList<Intent> list = stickies.get(intent.getAction());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011478 if (list == null) {
11479 list = new ArrayList<Intent>();
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011480 stickies.put(intent.getAction(), list);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011481 }
11482 int N = list.size();
11483 int i;
11484 for (i=0; i<N; i++) {
11485 if (intent.filterEquals(list.get(i))) {
11486 // This sticky already exists, replace it.
11487 list.set(i, new Intent(intent));
11488 break;
11489 }
11490 }
11491 if (i >= N) {
11492 list.add(new Intent(intent));
11493 }
11494 }
11495
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011496 int[] users;
11497 if (userId == UserHandle.USER_ALL) {
11498 // Caller wants broadcast to go to all started users.
11499 users = new int[mStartedUsers.size()];
11500 for (int i=0; i<mStartedUsers.size(); i++) {
11501 users[i] = mStartedUsers.keyAt(i);
11502 }
11503 } else {
11504 // Caller wants broadcast to go to one specific user.
11505 users = new int[] {userId};
11506 }
11507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011508 // Figure out who all will receive this broadcast.
11509 List receivers = null;
11510 List<BroadcastFilter> registeredReceivers = null;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011511 // Need to resolve the intent to interested receivers...
11512 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
11513 == 0) {
11514 receivers = collectReceiverComponents(intent, resolvedType, users);
11515 }
11516 if (intent.getComponent() == null) {
11517 registeredReceivers = mReceiverResolver.queryIntent(intent,
11518 resolvedType, false, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011519 }
11520
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011521 final boolean replacePending =
11522 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
11523
Joe Onorato8a9b2202010-02-26 18:56:32 -080011524 if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011525 + " replacePending=" + replacePending);
11526
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011527 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
11528 if (!ordered && NR > 0) {
11529 // If we are not serializing this broadcast, then send the
11530 // registered receivers separately so they don't wait for the
11531 // components to be launched.
Christopher Tatef46723b2012-01-26 14:19:24 -080011532 final BroadcastQueue queue = broadcastQueueForIntent(intent);
11533 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011534 callerPackage, callingPid, callingUid, requiredPermission,
11535 registeredReceivers, resultTo, resultCode, resultData, map,
Amith Yamasani8bf06ed2012-08-27 19:30:30 -070011536 ordered, sticky, false, userId);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011537 if (DEBUG_BROADCAST) Slog.v(
Christopher Tatef46723b2012-01-26 14:19:24 -080011538 TAG, "Enqueueing parallel broadcast " + r);
11539 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011540 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080011541 queue.enqueueParallelBroadcastLocked(r);
11542 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011543 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011544 registeredReceivers = null;
11545 NR = 0;
11546 }
11547
11548 // Merge into one list.
11549 int ir = 0;
11550 if (receivers != null) {
11551 // A special case for PACKAGE_ADDED: do not allow the package
11552 // being added to see this broadcast. This prevents them from
11553 // using this as a back door to get run as soon as they are
11554 // installed. Maybe in the future we want to have a special install
11555 // broadcast or such for apps, but we'd like to deliberately make
11556 // this decision.
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011557 String skipPackages[] = null;
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011558 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
11559 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
11560 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011561 Uri data = intent.getData();
11562 if (data != null) {
11563 String pkgName = data.getSchemeSpecificPart();
11564 if (pkgName != null) {
11565 skipPackages = new String[] { pkgName };
11566 }
11567 }
Dianne Hackborn0f1de9a2011-05-11 17:34:49 -070011568 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011569 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
The Android Open Source Project10592532009-03-18 17:39:46 -070011570 }
Suchi Amalapurapu08675a32010-01-28 09:57:30 -080011571 if (skipPackages != null && (skipPackages.length > 0)) {
11572 for (String skipPackage : skipPackages) {
11573 if (skipPackage != null) {
11574 int NT = receivers.size();
11575 for (int it=0; it<NT; it++) {
11576 ResolveInfo curt = (ResolveInfo)receivers.get(it);
11577 if (curt.activityInfo.packageName.equals(skipPackage)) {
11578 receivers.remove(it);
11579 it--;
11580 NT--;
11581 }
11582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011583 }
11584 }
11585 }
11586
11587 int NT = receivers != null ? receivers.size() : 0;
11588 int it = 0;
11589 ResolveInfo curt = null;
11590 BroadcastFilter curr = null;
11591 while (it < NT && ir < NR) {
11592 if (curt == null) {
11593 curt = (ResolveInfo)receivers.get(it);
11594 }
11595 if (curr == null) {
11596 curr = registeredReceivers.get(ir);
11597 }
11598 if (curr.getPriority() >= curt.priority) {
11599 // Insert this broadcast record into the final list.
11600 receivers.add(it, curr);
11601 ir++;
11602 curr = null;
11603 it++;
11604 NT++;
11605 } else {
11606 // Skip to the next ResolveInfo in the final list.
11607 it++;
11608 curt = null;
11609 }
11610 }
11611 }
11612 while (ir < NR) {
11613 if (receivers == null) {
11614 receivers = new ArrayList();
11615 }
11616 receivers.add(registeredReceivers.get(ir));
11617 ir++;
11618 }
11619
11620 if ((receivers != null && receivers.size() > 0)
11621 || resultTo != null) {
Christopher Tatef46723b2012-01-26 14:19:24 -080011622 BroadcastQueue queue = broadcastQueueForIntent(intent);
11623 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011624 callerPackage, callingPid, callingUid, requiredPermission,
Dianne Hackborn12527f92009-11-11 17:39:50 -080011625 receivers, resultTo, resultCode, resultData, map, ordered,
Amith Yamasani8bf06ed2012-08-27 19:30:30 -070011626 sticky, false, userId);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011627 if (DEBUG_BROADCAST) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011628 TAG, "Enqueueing ordered broadcast " + r
Christopher Tatef46723b2012-01-26 14:19:24 -080011629 + ": prev had " + queue.mOrderedBroadcasts.size());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011630 if (DEBUG_BROADCAST) {
11631 int seq = r.intent.getIntExtra("seq", -1);
Joe Onorato8a9b2202010-02-26 18:56:32 -080011632 Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011633 }
Christopher Tatef46723b2012-01-26 14:19:24 -080011634 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011635 if (!replaced) {
Christopher Tatef46723b2012-01-26 14:19:24 -080011636 queue.enqueueOrderedBroadcastLocked(r);
11637 queue.scheduleBroadcastsLocked();
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080011638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011639 }
11640
Dianne Hackborna4972e92012-03-14 10:38:05 -070011641 return ActivityManager.BROADCAST_SUCCESS;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011642 }
11643
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011644 final Intent verifyBroadcastLocked(Intent intent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011645 // Refuse possible leaked file descriptors
11646 if (intent != null && intent.hasFileDescriptors() == true) {
11647 throw new IllegalArgumentException("File descriptors passed in Intent");
11648 }
11649
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011650 int flags = intent.getFlags();
11651
11652 if (!mProcessesReady) {
11653 // if the caller really truly claims to know what they're doing, go
11654 // ahead and allow the broadcast without launching any receivers
11655 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
11656 intent = new Intent(intent);
11657 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
11658 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
11659 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
11660 + " before boot completion");
11661 throw new IllegalStateException("Cannot broadcast before boot completed");
11662 }
11663 }
11664
11665 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
11666 throw new IllegalArgumentException(
11667 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
11668 }
11669
11670 return intent;
11671 }
11672
11673 public final int broadcastIntent(IApplicationThread caller,
11674 Intent intent, String resolvedType, IIntentReceiver resultTo,
11675 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070011676 String requiredPermission, boolean serialized, boolean sticky, int userId) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011677 enforceNotIsolatedCaller("broadcastIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011678 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011679 intent = verifyBroadcastLocked(intent);
Dianne Hackborn9acc0302009-08-25 00:27:12 -070011680
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011681 final ProcessRecord callerApp = getRecordForAppLocked(caller);
11682 final int callingPid = Binder.getCallingPid();
11683 final int callingUid = Binder.getCallingUid();
11684 final long origId = Binder.clearCallingIdentity();
11685 int res = broadcastIntentLocked(callerApp,
11686 callerApp != null ? callerApp.info.packageName : null,
11687 intent, resolvedType, resultTo,
Amith Yamasani742a6712011-05-04 14:49:28 -070011688 resultCode, resultData, map, requiredPermission, serialized, sticky,
11689 callingPid, callingUid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011690 Binder.restoreCallingIdentity(origId);
11691 return res;
11692 }
11693 }
11694
11695 int broadcastIntentInPackage(String packageName, int uid,
11696 Intent intent, String resolvedType, IIntentReceiver resultTo,
11697 int resultCode, String resultData, Bundle map,
Amith Yamasani742a6712011-05-04 14:49:28 -070011698 String requiredPermission, boolean serialized, boolean sticky, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011699 synchronized(this) {
Dianne Hackborn8891fdc2010-09-20 20:44:46 -070011700 intent = verifyBroadcastLocked(intent);
11701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011702 final long origId = Binder.clearCallingIdentity();
11703 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
11704 resultTo, resultCode, resultData, map, requiredPermission,
Amith Yamasani742a6712011-05-04 14:49:28 -070011705 serialized, sticky, -1, uid, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011706 Binder.restoreCallingIdentity(origId);
11707 return res;
11708 }
11709 }
11710
Amith Yamasani742a6712011-05-04 14:49:28 -070011711 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011712 // Refuse possible leaked file descriptors
11713 if (intent != null && intent.hasFileDescriptors() == true) {
11714 throw new IllegalArgumentException("File descriptors passed in Intent");
11715 }
11716
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011717 userId = handleIncomingUserLocked(Binder.getCallingPid(),
11718 Binder.getCallingUid(), userId, true, false, "removeStickyBroadcast", null);
11719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011720 synchronized(this) {
11721 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
11722 != PackageManager.PERMISSION_GRANTED) {
11723 String msg = "Permission Denial: unbroadcastIntent() from pid="
11724 + Binder.getCallingPid()
11725 + ", uid=" + Binder.getCallingUid()
11726 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
Joe Onorato8a9b2202010-02-26 18:56:32 -080011727 Slog.w(TAG, msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011728 throw new SecurityException(msg);
11729 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011730 HashMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
11731 if (stickies != null) {
11732 ArrayList<Intent> list = stickies.get(intent.getAction());
11733 if (list != null) {
11734 int N = list.size();
11735 int i;
11736 for (i=0; i<N; i++) {
11737 if (intent.filterEquals(list.get(i))) {
11738 list.remove(i);
11739 break;
11740 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011741 }
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070011742 if (list.size() <= 0) {
11743 stickies.remove(intent.getAction());
11744 }
11745 }
11746 if (stickies.size() <= 0) {
11747 mStickyBroadcasts.remove(userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011748 }
11749 }
11750 }
11751 }
11752
11753 private final boolean finishReceiverLocked(IBinder receiver, int resultCode,
11754 String resultData, Bundle resultExtras, boolean resultAbort,
11755 boolean explicit) {
Christopher Tatef46723b2012-01-26 14:19:24 -080011756 final BroadcastRecord r = broadcastRecordForReceiverLocked(receiver);
11757 if (r == null) {
11758 Slog.w(TAG, "finishReceiver called but not found on queue");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011759 return false;
11760 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011761
Christopher Tatef46723b2012-01-26 14:19:24 -080011762 return r.queue.finishReceiverLocked(r, resultCode, resultData, resultExtras, resultAbort,
11763 explicit);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011764 }
11765
11766 public void finishReceiver(IBinder who, int resultCode, String resultData,
11767 Bundle resultExtras, boolean resultAbort) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011768 if (DEBUG_BROADCAST) Slog.v(TAG, "Finish receiver: " + who);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011769
11770 // Refuse possible leaked file descriptors
11771 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
11772 throw new IllegalArgumentException("File descriptors passed in Bundle");
11773 }
11774
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011775 final long origId = Binder.clearCallingIdentity();
Christopher Tatef46723b2012-01-26 14:19:24 -080011776 try {
11777 boolean doNext = false;
11778 BroadcastRecord r = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011779
Christopher Tatef46723b2012-01-26 14:19:24 -080011780 synchronized(this) {
11781 r = broadcastRecordForReceiverLocked(who);
11782 if (r != null) {
11783 doNext = r.queue.finishReceiverLocked(r, resultCode,
11784 resultData, resultExtras, resultAbort, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011785 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011786 }
Jeff Brown4d94a762010-09-23 11:33:28 -070011787
Christopher Tatef46723b2012-01-26 14:19:24 -080011788 if (doNext) {
11789 r.queue.processNextBroadcast(false);
11790 }
11791 trimApplications();
11792 } finally {
11793 Binder.restoreCallingIdentity(origId);
Dianne Hackbornad5499d2010-03-29 18:08:45 -070011794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011796
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011797 // =========================================================
11798 // INSTRUMENTATION
11799 // =========================================================
11800
11801 public boolean startInstrumentation(ComponentName className,
11802 String profileFile, int flags, Bundle arguments,
11803 IInstrumentationWatcher watcher) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -080011804 enforceNotIsolatedCaller("startInstrumentation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011805 // Refuse possible leaked file descriptors
11806 if (arguments != null && arguments.hasFileDescriptors()) {
11807 throw new IllegalArgumentException("File descriptors passed in Bundle");
11808 }
11809
11810 synchronized(this) {
11811 InstrumentationInfo ii = null;
11812 ApplicationInfo ai = null;
11813 try {
11814 ii = mContext.getPackageManager().getInstrumentationInfo(
Dianne Hackborn1655be42009-05-08 14:29:01 -070011815 className, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011816 ai = mContext.getPackageManager().getApplicationInfo(
Amith Yamasani483f3b02012-03-13 16:08:00 -070011817 ii.targetPackage, STOCK_PM_FLAGS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011818 } catch (PackageManager.NameNotFoundException e) {
11819 }
11820 if (ii == null) {
11821 reportStartInstrumentationFailure(watcher, className,
11822 "Unable to find instrumentation info for: " + className);
11823 return false;
11824 }
11825 if (ai == null) {
11826 reportStartInstrumentationFailure(watcher, className,
11827 "Unable to find instrumentation target package: " + ii.targetPackage);
11828 return false;
11829 }
11830
11831 int match = mContext.getPackageManager().checkSignatures(
11832 ii.targetPackage, ii.packageName);
11833 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
11834 String msg = "Permission Denial: starting instrumentation "
11835 + className + " from pid="
11836 + Binder.getCallingPid()
11837 + ", uid=" + Binder.getCallingPid()
11838 + " not allowed because package " + ii.packageName
11839 + " does not have a signature matching the target "
11840 + ii.targetPackage;
11841 reportStartInstrumentationFailure(watcher, className, msg);
11842 throw new SecurityException(msg);
11843 }
11844
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070011845 int userId = UserHandle.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011846 final long origId = Binder.clearCallingIdentity();
Christopher Tate3dacd842011-08-19 14:56:15 -070011847 // Instrumentation can kill and relaunch even persistent processes
Amith Yamasani483f3b02012-03-13 16:08:00 -070011848 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, userId);
Dianne Hackborna0c283e2012-02-09 10:47:01 -080011849 ProcessRecord app = addAppLocked(ai, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850 app.instrumentationClass = className;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011851 app.instrumentationInfo = ai;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011852 app.instrumentationProfileFile = profileFile;
11853 app.instrumentationArguments = arguments;
11854 app.instrumentationWatcher = watcher;
11855 app.instrumentationResultClass = className;
11856 Binder.restoreCallingIdentity(origId);
11857 }
11858
11859 return true;
11860 }
11861
11862 /**
11863 * Report errors that occur while attempting to start Instrumentation. Always writes the
11864 * error to the logs, but if somebody is watching, send the report there too. This enables
11865 * the "am" command to report errors with more information.
11866 *
11867 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
11868 * @param cn The component name of the instrumentation.
11869 * @param report The error report.
11870 */
11871 private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
11872 ComponentName cn, String report) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011873 Slog.w(TAG, report);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011874 try {
11875 if (watcher != null) {
11876 Bundle results = new Bundle();
11877 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
11878 results.putString("Error", report);
11879 watcher.instrumentationStatus(cn, -1, results);
11880 }
11881 } catch (RemoteException e) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011882 Slog.w(TAG, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 }
11884 }
11885
11886 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
11887 if (app.instrumentationWatcher != null) {
11888 try {
11889 // NOTE: IInstrumentationWatcher *must* be oneway here
11890 app.instrumentationWatcher.instrumentationFinished(
11891 app.instrumentationClass,
11892 resultCode,
11893 results);
11894 } catch (RemoteException e) {
11895 }
11896 }
11897 app.instrumentationWatcher = null;
11898 app.instrumentationClass = null;
Dianne Hackborn1655be42009-05-08 14:29:01 -070011899 app.instrumentationInfo = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011900 app.instrumentationProfileFile = null;
11901 app.instrumentationArguments = null;
11902
Dianne Hackborn80a4af22012-08-27 19:18:31 -070011903 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, app.userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011904 }
11905
11906 public void finishInstrumentation(IApplicationThread target,
11907 int resultCode, Bundle results) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070011908 int userId = UserHandle.getCallingUserId();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011909 // Refuse possible leaked file descriptors
11910 if (results != null && results.hasFileDescriptors()) {
11911 throw new IllegalArgumentException("File descriptors passed in Intent");
11912 }
11913
11914 synchronized(this) {
11915 ProcessRecord app = getRecordForAppLocked(target);
11916 if (app == null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080011917 Slog.w(TAG, "finishInstrumentation: no app for " + target);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011918 return;
11919 }
11920 final long origId = Binder.clearCallingIdentity();
11921 finishInstrumentationLocked(app, resultCode, results);
11922 Binder.restoreCallingIdentity(origId);
11923 }
11924 }
11925
11926 // =========================================================
11927 // CONFIGURATION
11928 // =========================================================
11929
11930 public ConfigurationInfo getDeviceConfigurationInfo() {
11931 ConfigurationInfo config = new ConfigurationInfo();
11932 synchronized (this) {
11933 config.reqTouchScreen = mConfiguration.touchscreen;
11934 config.reqKeyboardType = mConfiguration.keyboard;
11935 config.reqNavigation = mConfiguration.navigation;
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011936 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
11937 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011938 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
11939 }
Dianne Hackbornfae76f52009-07-16 13:41:23 -070011940 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
11941 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011942 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
11943 }
Jack Palevichb90d28c2009-07-22 15:35:24 -070011944 config.reqGlEsVersion = GL_ES_VERSION;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011945 }
11946 return config;
11947 }
11948
11949 public Configuration getConfiguration() {
11950 Configuration ci;
11951 synchronized(this) {
11952 ci = new Configuration(mConfiguration);
11953 }
11954 return ci;
11955 }
11956
Dianne Hackborn31ca8542011-07-19 14:58:28 -070011957 public void updatePersistentConfiguration(Configuration values) {
11958 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11959 "updateConfiguration()");
11960 enforceCallingPermission(android.Manifest.permission.WRITE_SETTINGS,
11961 "updateConfiguration()");
11962 if (values == null) {
11963 throw new NullPointerException("Configuration must not be null");
11964 }
11965
11966 synchronized(this) {
11967 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn813075a62011-11-14 17:45:19 -080011968 updateConfigurationLocked(values, null, true, false);
Dianne Hackborn31ca8542011-07-19 14:58:28 -070011969 Binder.restoreCallingIdentity(origId);
11970 }
11971 }
11972
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011973 public void updateConfiguration(Configuration values) {
11974 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
11975 "updateConfiguration()");
11976
11977 synchronized(this) {
11978 if (values == null && mWindowManager != null) {
11979 // sentinel: fetch the current configuration from the window manager
11980 values = mWindowManager.computeNewConfiguration();
11981 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070011982
11983 if (mWindowManager != null) {
11984 mProcessList.applyDisplaySize(mWindowManager);
11985 }
11986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011987 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn31ca8542011-07-19 14:58:28 -070011988 if (values != null) {
11989 Settings.System.clearConfiguration(values);
11990 }
Dianne Hackborn813075a62011-11-14 17:45:19 -080011991 updateConfigurationLocked(values, null, false, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011992 Binder.restoreCallingIdentity(origId);
11993 }
11994 }
11995
11996 /**
11997 * Do either or both things: (1) change the current configuration, and (2)
11998 * make sure the given activity is running with the (now) current
11999 * configuration. Returns true if the activity has been left running, or
12000 * false if <var>starting</var> is being destroyed to match the new
12001 * configuration.
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012002 * @param persistent TODO
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012003 */
Dianne Hackborna573f6a2012-02-09 16:12:18 -080012004 boolean updateConfigurationLocked(Configuration values,
Dianne Hackborn813075a62011-11-14 17:45:19 -080012005 ActivityRecord starting, boolean persistent, boolean initLocale) {
Mike Lockwood3a74bd32011-08-12 13:55:22 -070012006 // do nothing if we are headless
12007 if (mHeadless) return true;
12008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012009 int changes = 0;
12010
12011 boolean kept = true;
12012
12013 if (values != null) {
12014 Configuration newConfig = new Configuration(mConfiguration);
12015 changes = newConfig.updateFrom(values);
12016 if (changes != 0) {
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012017 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012018 Slog.i(TAG, "Updating configuration to: " + values);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012019 }
12020
Doug Zongker2bec3d42009-12-04 12:52:44 -080012021 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012022
Dianne Hackborn813075a62011-11-14 17:45:19 -080012023 if (values.locale != null && !initLocale) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012024 saveLocaleLocked(values.locale,
12025 !values.locale.equals(mConfiguration.locale),
12026 values.userSetLocale);
12027 }
12028
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012029 mConfigurationSeq++;
12030 if (mConfigurationSeq <= 0) {
12031 mConfigurationSeq = 1;
12032 }
12033 newConfig.seq = mConfigurationSeq;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012034 mConfiguration = newConfig;
Joe Onorato8a9b2202010-02-26 18:56:32 -080012035 Slog.i(TAG, "Config changed: " + newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012036
12037 final Configuration configCopy = new Configuration(mConfiguration);
Joe Onorato54a4a412011-11-02 20:50:08 -070012038
12039 // TODO: If our config changes, should we auto dismiss any currently
12040 // showing dialogs?
12041 mShowDialogs = shouldShowDialogs(newConfig);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012042
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012043 AttributeCache ac = AttributeCache.instance();
12044 if (ac != null) {
Dianne Hackborn813075a62011-11-14 17:45:19 -080012045 ac.updateConfiguration(configCopy);
Dianne Hackborn826d17c2009-11-12 12:55:51 -080012046 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012047
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012048 // Make sure all resources in our process are updated
12049 // right now, so that anyone who is going to retrieve
12050 // resource values after we return will be sure to get
12051 // the new ones. This is especially important during
12052 // boot, where the first config change needs to guarantee
12053 // all resources have that config before following boot
12054 // code is executed.
Dianne Hackborn813075a62011-11-14 17:45:19 -080012055 mSystemThread.applyConfigurationToResources(configCopy);
Dianne Hackborn2f0b1752011-05-31 17:59:49 -070012056
Dianne Hackborn31ca8542011-07-19 14:58:28 -070012057 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012058 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012059 msg.obj = new Configuration(configCopy);
Dianne Hackbornb8b11a02010-03-10 15:53:11 -080012060 mHandler.sendMessage(msg);
12061 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012062
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012063 for (int i=mLruProcesses.size()-1; i>=0; i--) {
12064 ProcessRecord app = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012065 try {
12066 if (app.thread != null) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012067 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
Dianne Hackborndc6b6352009-09-30 14:20:09 -070012068 + app.processName + " new config " + mConfiguration);
Dianne Hackborn813075a62011-11-14 17:45:19 -080012069 app.thread.scheduleConfigurationChanged(configCopy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012070 }
12071 } catch (Exception e) {
12072 }
12073 }
12074 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
Dianne Hackborn1c633fc2009-12-08 19:45:14 -080012075 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12076 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012077 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070012078 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012079 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
12080 broadcastIntentLocked(null, null,
12081 new Intent(Intent.ACTION_LOCALE_CHANGED),
12082 null, null, 0, null, null,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070012083 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
Dianne Hackborn362d5b92009-11-11 18:04:39 -080012084 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012085 }
12086 }
12087
12088 if (changes != 0 && starting == null) {
12089 // If the configuration changed, and the caller is not already
12090 // in the process of starting an activity, then find the top
12091 // activity to check if its configuration needs to change.
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012092 starting = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012093 }
12094
12095 if (starting != null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012096 kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
Dianne Hackborn5f4d6432010-12-21 20:40:11 -080012097 // And we need to make sure at this point that all other activities
12098 // are made visible with the correct configuration.
12099 mMainStack.ensureActivitiesVisibleLocked(starting, changes);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012100 }
12101
Dianne Hackborne36d6e22010-02-17 19:46:25 -080012102 if (values != null && mWindowManager != null) {
12103 mWindowManager.setNewConfiguration(mConfiguration);
12104 }
12105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012106 return kept;
12107 }
Joe Onorato54a4a412011-11-02 20:50:08 -070012108
12109 /**
12110 * Decide based on the configuration whether we should shouw the ANR,
12111 * crash, etc dialogs. The idea is that if there is no affordnace to
12112 * press the on-screen buttons, we shouldn't show the dialog.
12113 *
12114 * A thought: SystemUI might also want to get told about this, the Power
12115 * dialog / global actions also might want different behaviors.
12116 */
12117 private static final boolean shouldShowDialogs(Configuration config) {
12118 return !(config.keyboard == Configuration.KEYBOARD_NOKEYS
12119 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH);
12120 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012121
12122 /**
12123 * Save the locale. You must be inside a synchronized (this) block.
12124 */
12125 private void saveLocaleLocked(Locale l, boolean isDiff, boolean isPersist) {
12126 if(isDiff) {
12127 SystemProperties.set("user.language", l.getLanguage());
12128 SystemProperties.set("user.region", l.getCountry());
12129 }
12130
12131 if(isPersist) {
12132 SystemProperties.set("persist.sys.language", l.getLanguage());
12133 SystemProperties.set("persist.sys.country", l.getCountry());
12134 SystemProperties.set("persist.sys.localevar", l.getVariant());
12135 }
12136 }
12137
Adam Powelldd8fab22012-03-22 17:47:27 -070012138 @Override
12139 public boolean targetTaskAffinityMatchesActivity(IBinder token, String destAffinity) {
12140 ActivityRecord srec = ActivityRecord.forToken(token);
Adam Powellb71a5bc2012-04-24 14:20:57 -070012141 return srec != null && srec.task.affinity != null &&
12142 srec.task.affinity.equals(destAffinity);
Adam Powelldd8fab22012-03-22 17:47:27 -070012143 }
12144
12145 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
12146 Intent resultData) {
12147 ComponentName dest = destIntent.getComponent();
12148
12149 synchronized (this) {
12150 ActivityRecord srec = ActivityRecord.forToken(token);
Adam Powellb71a5bc2012-04-24 14:20:57 -070012151 if (srec == null) {
12152 return false;
12153 }
Adam Powelldd8fab22012-03-22 17:47:27 -070012154 ArrayList<ActivityRecord> history = srec.stack.mHistory;
12155 final int start = history.indexOf(srec);
12156 if (start < 0) {
12157 // Current activity is not in history stack; do nothing.
12158 return false;
12159 }
12160 int finishTo = start - 1;
12161 ActivityRecord parent = null;
12162 boolean foundParentInTask = false;
12163 if (dest != null) {
12164 TaskRecord tr = srec.task;
12165 for (int i = start - 1; i >= 0; i--) {
12166 ActivityRecord r = history.get(i);
12167 if (tr != r.task) {
12168 // Couldn't find parent in the same task; stop at the one above this.
12169 // (Root of current task; in-app "home" behavior)
12170 // Always at least finish the current activity.
12171 finishTo = Math.min(start - 1, i + 1);
12172 parent = history.get(finishTo);
12173 break;
12174 } else if (r.info.packageName.equals(dest.getPackageName()) &&
12175 r.info.name.equals(dest.getClassName())) {
12176 finishTo = i;
12177 parent = r;
12178 foundParentInTask = true;
12179 break;
12180 }
12181 }
12182 }
12183
12184 if (mController != null) {
12185 ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
12186 if (next != null) {
12187 // ask watcher if this is allowed
12188 boolean resumeOK = true;
12189 try {
12190 resumeOK = mController.activityResuming(next.packageName);
12191 } catch (RemoteException e) {
12192 mController = null;
12193 }
12194
12195 if (!resumeOK) {
12196 return false;
12197 }
12198 }
12199 }
12200 final long origId = Binder.clearCallingIdentity();
12201 for (int i = start; i > finishTo; i--) {
12202 ActivityRecord r = history.get(i);
12203 mMainStack.requestFinishActivityLocked(r.appToken, resultCode, resultData,
12204 "navigate-up");
12205 // Only return the supplied result for the first activity finished
12206 resultCode = Activity.RESULT_CANCELED;
12207 resultData = null;
12208 }
12209
12210 if (parent != null && foundParentInTask) {
12211 final int parentLaunchMode = parent.info.launchMode;
12212 final int destIntentFlags = destIntent.getFlags();
12213 if (parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_INSTANCE ||
12214 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TASK ||
12215 parentLaunchMode == ActivityInfo.LAUNCH_SINGLE_TOP ||
12216 (destIntentFlags & Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
Adam Powell69de7e12012-05-07 18:42:24 -070012217 parent.deliverNewIntentLocked(srec.info.applicationInfo.uid, destIntent);
Adam Powelldd8fab22012-03-22 17:47:27 -070012218 } else {
12219 try {
12220 ActivityInfo aInfo = AppGlobals.getPackageManager().getActivityInfo(
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070012221 destIntent.getComponent(), 0, UserHandle.getCallingUserId());
Adam Powelldd8fab22012-03-22 17:47:27 -070012222 int res = mMainStack.startActivityLocked(srec.app.thread, destIntent,
12223 null, aInfo, parent.appToken, null,
12224 0, -1, parent.launchedFromUid, 0, null, true, null);
12225 foundParentInTask = res == ActivityManager.START_SUCCESS;
12226 } catch (RemoteException e) {
12227 foundParentInTask = false;
12228 }
12229 mMainStack.requestFinishActivityLocked(parent.appToken, resultCode,
12230 resultData, "navigate-up");
12231 }
12232 }
12233 Binder.restoreCallingIdentity(origId);
12234 return foundParentInTask;
12235 }
12236 }
12237
Dianne Hackborn5320eb82012-05-18 12:05:04 -070012238 public int getLaunchedFromUid(IBinder activityToken) {
12239 ActivityRecord srec = ActivityRecord.forToken(activityToken);
12240 if (srec == null) {
12241 return -1;
12242 }
12243 return srec.launchedFromUid;
12244 }
12245
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012246 // =========================================================
12247 // LIFETIME MANAGEMENT
12248 // =========================================================
12249
Christopher Tatef46723b2012-01-26 14:19:24 -080012250 // Returns which broadcast queue the app is the current [or imminent] receiver
12251 // on, or 'null' if the app is not an active broadcast recipient.
12252 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
12253 BroadcastRecord r = app.curReceiver;
12254 if (r != null) {
12255 return r.queue;
12256 }
12257
12258 // It's not the current receiver, but it might be starting up to become one
12259 synchronized (this) {
12260 for (BroadcastQueue queue : mBroadcastQueues) {
12261 r = queue.mPendingBroadcast;
12262 if (r != null && r.curApp == app) {
12263 // found it; report which queue it's in
12264 return queue;
12265 }
12266 }
12267 }
12268
12269 return null;
12270 }
12271
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012272 private final int computeOomAdjLocked(ProcessRecord app, int hiddenAdj,
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012273 int emptyAdj, ProcessRecord TOP_APP, boolean recursed, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012274 if (mAdjSeq == app.adjSeq) {
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012275 // This adjustment has already been computed. If we are calling
12276 // from the top, we may have already computed our adjustment with
12277 // an earlier hidden adjustment that isn't really for us... if
12278 // so, use the new hidden adjustment.
12279 if (!recursed && app.hidden) {
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012280 app.curAdj = app.curRawAdj = app.nonStoppingAdj =
12281 app.hasActivities ? hiddenAdj : emptyAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012282 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012283 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012284 }
12285
12286 if (app.thread == null) {
12287 app.adjSeq = mAdjSeq;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012288 app.curSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012289 return (app.curAdj=app.curRawAdj=ProcessList.HIDDEN_APP_MAX_ADJ);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012290 }
12291
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012292 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
12293 app.adjSource = null;
12294 app.adjTarget = null;
12295 app.empty = false;
12296 app.hidden = false;
12297
12298 final int activitiesSize = app.activities.size();
12299
Dianne Hackborn7d608422011-08-07 16:24:18 -070012300 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012301 // The max adjustment doesn't allow this app to be anything
12302 // below foreground, so it is not worth doing work for it.
12303 app.adjType = "fixed";
12304 app.adjSeq = mAdjSeq;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012305 app.curRawAdj = app.nonStoppingAdj = app.maxAdj;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012306 app.hasActivities = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012307 app.foregroundActivities = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012308 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012309 app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012310 // System process can do UI, and when they do we want to have
12311 // them trim their memory after the user leaves the UI. To
12312 // facilitate this, here we need to determine whether or not it
12313 // is currently showing UI.
12314 app.systemNoUi = true;
12315 if (app == TOP_APP) {
12316 app.systemNoUi = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012317 app.hasActivities = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012318 } else if (activitiesSize > 0) {
12319 for (int j = 0; j < activitiesSize; j++) {
12320 final ActivityRecord r = app.activities.get(j);
12321 if (r.visible) {
12322 app.systemNoUi = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012323 }
12324 if (r.app == app) {
12325 app.hasActivities = true;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012326 }
12327 }
12328 }
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012329 return (app.curAdj=app.maxAdj);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012330 }
12331
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012332 app.keeping = false;
12333 app.systemNoUi = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012334 app.hasActivities = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012335
The Android Open Source Project4df24232009-03-05 14:34:35 -080012336 // Determine the importance of the process, starting with most
12337 // important to least, and assign an appropriate OOM adjustment.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012338 int adj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012339 int schedGroup;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012340 boolean foregroundActivities = false;
12341 boolean interesting = false;
Christopher Tatef46723b2012-01-26 14:19:24 -080012342 BroadcastQueue queue;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012343 if (app == TOP_APP) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012344 // The last app on the list is the foreground app.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012345 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012346 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012347 app.adjType = "top-activity";
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012348 foregroundActivities = true;
12349 interesting = true;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012350 app.hasActivities = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012351 } else if (app.instrumentationClass != null) {
12352 // Don't want to kill running instrumentation.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012353 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012354 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012355 app.adjType = "instrumentation";
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012356 interesting = true;
Christopher Tatef46723b2012-01-26 14:19:24 -080012357 } else if ((queue = isReceivingBroadcast(app)) != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012358 // An app that is currently receiving a broadcast also
Christopher Tatef46723b2012-01-26 14:19:24 -080012359 // counts as being in the foreground for OOM killer purposes.
12360 // It's placed in a sched group based on the nature of the
12361 // broadcast as reflected by which queue it's active in.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012362 adj = ProcessList.FOREGROUND_APP_ADJ;
Christopher Tatef46723b2012-01-26 14:19:24 -080012363 schedGroup = (queue == mFgBroadcastQueue)
12364 ? Process.THREAD_GROUP_DEFAULT : Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012365 app.adjType = "broadcast";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012366 } else if (app.executingServices.size() > 0) {
12367 // An app that is currently executing a service callback also
12368 // counts as being in the foreground.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012369 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012370 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012371 app.adjType = "exec-service";
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012372 } else {
12373 // Assume process is hidden (has activities); we will correct
12374 // later if this is not the case.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012375 adj = hiddenAdj;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012376 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012377 app.hidden = true;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012378 app.adjType = "bg-activities";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012379 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012380
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012381 boolean hasStoppingActivities = false;
12382
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012383 // Examine all activities if not already foreground.
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012384 if (!foregroundActivities && activitiesSize > 0) {
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012385 for (int j = 0; j < activitiesSize; j++) {
12386 final ActivityRecord r = app.activities.get(j);
12387 if (r.visible) {
12388 // App has a visible activity; only upgrade adjustment.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012389 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12390 adj = ProcessList.VISIBLE_APP_ADJ;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012391 app.adjType = "visible";
12392 }
12393 schedGroup = Process.THREAD_GROUP_DEFAULT;
12394 app.hidden = false;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012395 app.hasActivities = true;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012396 foregroundActivities = true;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012397 break;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012398 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012399 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12400 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012401 app.adjType = "pausing";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012402 }
Dianne Hackborn8bf0aa92011-11-29 13:54:43 -080012403 app.hidden = false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012404 foregroundActivities = true;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012405 } else if (r.state == ActivityState.STOPPING) {
12406 // We will apply the actual adjustment later, because
12407 // we want to allow this process to immediately go through
12408 // any memory trimming that is in effect.
12409 app.hidden = false;
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012410 foregroundActivities = true;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012411 hasStoppingActivities = true;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012412 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012413 if (r.app == app) {
12414 app.hasActivities = true;
12415 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012416 }
12417 }
12418
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012419 if (adj == hiddenAdj && !app.hasActivities) {
12420 // Whoops, this process is completely empty as far as we know
12421 // at this point.
12422 adj = emptyAdj;
12423 app.empty = true;
12424 app.adjType = "bg-empty";
12425 }
12426
Dianne Hackborn7d608422011-08-07 16:24:18 -070012427 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012428 if (app.foregroundServices) {
12429 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012430 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012431 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012432 app.adjType = "foreground-service";
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012433 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012434 } else if (app.forcingToForeground != null) {
12435 // The user is aware of this app, so make it visible.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012436 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012437 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012438 app.adjType = "force-foreground";
12439 app.adjSource = app.forcingToForeground;
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012440 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012441 }
12442 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012443
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012444 if (app.foregroundServices) {
12445 interesting = true;
12446 }
12447
Dianne Hackborn7d608422011-08-07 16:24:18 -070012448 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ && app == mHeavyWeightProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012449 // We don't want to kill the current heavy-weight process.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012450 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012451 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012452 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012453 app.adjType = "heavy";
12454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012455
Dianne Hackborn7d608422011-08-07 16:24:18 -070012456 if (adj > ProcessList.HOME_APP_ADJ && app == mHomeProcess) {
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012457 // This process is hosting what we currently consider to be the
12458 // home app, so we don't want to let it go into the background.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012459 adj = ProcessList.HOME_APP_ADJ;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012460 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012461 app.hidden = false;
Dianne Hackborn83a6f452011-01-27 17:17:19 -080012462 app.adjType = "home";
12463 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012464
Dianne Hackbornf35fe232011-11-01 19:25:20 -070012465 if (adj > ProcessList.PREVIOUS_APP_ADJ && app == mPreviousProcess
12466 && app.activities.size() > 0) {
12467 // This was the previous process that showed UI to the user.
12468 // We want to try to keep it around more aggressively, to give
12469 // a good experience around switching between two apps.
12470 adj = ProcessList.PREVIOUS_APP_ADJ;
12471 schedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
12472 app.hidden = false;
12473 app.adjType = "previous";
12474 }
12475
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012476 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
12477 + " reason=" + app.adjType);
12478
The Android Open Source Project4df24232009-03-05 14:34:35 -080012479 // By default, we use the computed adjustment. It may be changed if
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012480 // there are applications dependent on our services or providers, but
12481 // this gives us a baseline and makes sure we don't get into an
12482 // infinite recursion.
12483 app.adjSeq = mAdjSeq;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012484 app.curRawAdj = app.nonStoppingAdj = adj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012485
Christopher Tate6fa95972009-06-05 18:43:55 -070012486 if (mBackupTarget != null && app == mBackupTarget.app) {
12487 // If possible we want to avoid killing apps while they're being backed up
Dianne Hackborn7d608422011-08-07 16:24:18 -070012488 if (adj > ProcessList.BACKUP_APP_ADJ) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080012489 if (DEBUG_BACKUP) Slog.v(TAG, "oom BACKUP_APP_ADJ for " + app);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012490 adj = ProcessList.BACKUP_APP_ADJ;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012491 app.adjType = "backup";
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012492 app.hidden = false;
Christopher Tate6fa95972009-06-05 18:43:55 -070012493 }
12494 }
12495
Dianne Hackborn7d608422011-08-07 16:24:18 -070012496 if (app.services.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012497 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012498 final long now = SystemClock.uptimeMillis();
12499 // This process is more important if the top activity is
12500 // bound to the service.
Dianne Hackborn860755f2010-06-03 18:47:52 -070012501 Iterator<ServiceRecord> jt = app.services.iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012502 while (jt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012503 ServiceRecord s = jt.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012504 if (s.startRequested) {
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012505 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012506 // If this process has shown some UI, let it immediately
12507 // go to the LRU list because it may be pretty heavy with
12508 // UI stuff. We'll tag it with a label just to help
12509 // debug and understand what is going on.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012510 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012511 app.adjType = "started-bg-ui-services";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012512 }
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012513 } else {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070012514 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012515 // This service has seen some activity within
12516 // recent memory, so we will keep its process ahead
12517 // of the background processes.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012518 if (adj > ProcessList.SERVICE_ADJ) {
12519 adj = ProcessList.SERVICE_ADJ;
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012520 app.adjType = "started-services";
12521 app.hidden = false;
12522 }
12523 }
12524 // If we have let the service slide into the background
12525 // state, still have some text describing what it is doing
12526 // even though the service no longer has an impact.
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012527 if (adj > ProcessList.SERVICE_ADJ) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -070012528 app.adjType = "started-bg-services";
12529 }
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080012530 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070012531 // Don't kill this process because it is doing work; it
12532 // has said it is doing work.
12533 app.keeping = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012534 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012535 if (s.connections.size() > 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012536 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012537 Iterator<ArrayList<ConnectionRecord>> kt
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012538 = s.connections.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012539 while (kt.hasNext() && adj > ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012540 ArrayList<ConnectionRecord> clist = kt.next();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012541 for (int i=0; i<clist.size() && adj > ProcessList.FOREGROUND_APP_ADJ; i++) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012542 // XXX should compute this based on the max of
12543 // all connected clients.
12544 ConnectionRecord cr = clist.get(i);
12545 if (cr.binding.client == app) {
12546 // Binding to ourself is not interesting.
12547 continue;
12548 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012549 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012550 ProcessRecord client = cr.binding.client;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012551 int clientAdj = adj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012552 int myHiddenAdj = hiddenAdj;
12553 if (myHiddenAdj > client.hiddenAdj) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012554 if (client.hiddenAdj >= ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012555 myHiddenAdj = client.hiddenAdj;
12556 } else {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012557 myHiddenAdj = ProcessList.VISIBLE_APP_ADJ;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012558 }
12559 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012560 int myEmptyAdj = emptyAdj;
12561 if (myEmptyAdj > client.emptyAdj) {
12562 if (client.emptyAdj >= ProcessList.VISIBLE_APP_ADJ) {
12563 myEmptyAdj = client.emptyAdj;
12564 } else {
12565 myEmptyAdj = ProcessList.VISIBLE_APP_ADJ;
12566 }
12567 }
12568 clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12569 myEmptyAdj, TOP_APP, true, doingAll);
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012570 String adjType = null;
12571 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
12572 // Not doing bind OOM management, so treat
12573 // this guy more like a started service.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012574 if (app.hasShownUi && app != mHomeProcess) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012575 // If this process has shown some UI, let it immediately
12576 // go to the LRU list because it may be pretty heavy with
12577 // UI stuff. We'll tag it with a label just to help
12578 // debug and understand what is going on.
12579 if (adj > clientAdj) {
12580 adjType = "bound-bg-ui-services";
12581 }
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012582 app.hidden = false;
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012583 clientAdj = adj;
12584 } else {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070012585 if (now >= (s.lastActivity
12586 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012587 // This service has not seen activity within
12588 // recent memory, so allow it to drop to the
12589 // LRU list if there is no other reason to keep
12590 // it around. We'll also tag it with a label just
12591 // to help debug and undertand what is going on.
12592 if (adj > clientAdj) {
12593 adjType = "bound-bg-services";
12594 }
12595 clientAdj = adj;
12596 }
12597 }
12598 }
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012599 if (adj > clientAdj) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012600 // If this process has recently shown UI, and
12601 // the process that is binding to it is less
12602 // important than being visible, then we don't
12603 // care about the binding as much as we care
12604 // about letting this process get into the LRU
12605 // list to be killed and restarted if needed for
12606 // memory.
Dianne Hackborn98cfebc2011-10-18 13:17:33 -070012607 if (app.hasShownUi && app != mHomeProcess
12608 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012609 adjType = "bound-bg-ui-services";
12610 } else {
12611 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
12612 |Context.BIND_IMPORTANT)) != 0) {
12613 adj = clientAdj;
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070012614 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
12615 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
12616 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12617 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12618 } else if (clientAdj > ProcessList.VISIBLE_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012619 adj = clientAdj;
12620 } else {
Dianne Hackborn2c84cfc2011-10-31 15:39:59 -070012621 app.pendingUiClean = true;
12622 if (adj > ProcessList.VISIBLE_APP_ADJ) {
12623 adj = ProcessList.VISIBLE_APP_ADJ;
12624 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012625 }
12626 if (!client.hidden) {
12627 app.hidden = false;
12628 }
12629 if (client.keeping) {
12630 app.keeping = true;
12631 }
12632 adjType = "service";
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012633 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070012634 }
12635 if (adjType != null) {
12636 app.adjType = adjType;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012637 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12638 .REASON_SERVICE_IN_USE;
12639 app.adjSource = cr.binding.client;
Dianne Hackborn905577f2011-09-07 18:31:28 -070012640 app.adjSourceOom = clientAdj;
Dianne Hackborn43d9ac82010-08-25 15:06:25 -070012641 app.adjTarget = s.name;
12642 }
12643 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12644 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12645 schedGroup = Process.THREAD_GROUP_DEFAULT;
12646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012647 }
12648 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012649 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
12650 ActivityRecord a = cr.activity;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012651 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012652 (a.visible || a.state == ActivityState.RESUMED
12653 || a.state == ActivityState.PAUSING)) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012654 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012655 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
12656 schedGroup = Process.THREAD_GROUP_DEFAULT;
12657 }
12658 app.hidden = false;
12659 app.adjType = "service";
12660 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12661 .REASON_SERVICE_IN_USE;
12662 app.adjSource = a;
Dianne Hackborn905577f2011-09-07 18:31:28 -070012663 app.adjSourceOom = adj;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012664 app.adjTarget = s.name;
12665 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012667 }
12668 }
12669 }
12670 }
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012671
Dianne Hackborn287952c2010-09-22 22:34:31 -070012672 // Finally, if this process has active services running in it, we
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012673 // would like to avoid killing it unless it would prevent the current
12674 // application from running. By default we put the process in
12675 // with the rest of the background processes; as we scan through
12676 // its services we may bump it up from there.
12677 if (adj > hiddenAdj) {
12678 adj = hiddenAdj;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012679 app.hidden = false;
Dianne Hackbornbcbcaa72009-09-10 10:54:46 -070012680 app.adjType = "bg-services";
12681 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012682 }
12683
Dianne Hackborn7d608422011-08-07 16:24:18 -070012684 if (app.pubProviders.size() != 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012685 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012686 Iterator<ContentProviderRecord> jt = app.pubProviders.values().iterator();
Dianne Hackborn7d608422011-08-07 16:24:18 -070012687 while (jt.hasNext() && (adj > ProcessList.FOREGROUND_APP_ADJ
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012688 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
Dianne Hackborn860755f2010-06-03 18:47:52 -070012689 ContentProviderRecord cpr = jt.next();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070012690 for (int i = cpr.connections.size()-1;
12691 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
12692 || schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE);
12693 i--) {
12694 ContentProviderConnection conn = cpr.connections.get(i);
12695 ProcessRecord client = conn.client;
12696 if (client == app) {
12697 // Being our own client is not interesting.
12698 continue;
12699 }
12700 int myHiddenAdj = hiddenAdj;
12701 if (myHiddenAdj > client.hiddenAdj) {
12702 if (client.hiddenAdj > ProcessList.FOREGROUND_APP_ADJ) {
12703 myHiddenAdj = client.hiddenAdj;
12704 } else {
12705 myHiddenAdj = ProcessList.FOREGROUND_APP_ADJ;
The Android Open Source Project10592532009-03-18 17:39:46 -070012706 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070012707 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070012708 int myEmptyAdj = emptyAdj;
12709 if (myEmptyAdj > client.emptyAdj) {
12710 if (client.emptyAdj > ProcessList.FOREGROUND_APP_ADJ) {
12711 myEmptyAdj = client.emptyAdj;
12712 } else {
12713 myEmptyAdj = ProcessList.FOREGROUND_APP_ADJ;
12714 }
12715 }
12716 int clientAdj = computeOomAdjLocked(client, myHiddenAdj,
12717 myEmptyAdj, TOP_APP, true, doingAll);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070012718 if (adj > clientAdj) {
12719 if (app.hasShownUi && app != mHomeProcess
12720 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12721 app.adjType = "bg-ui-provider";
12722 } else {
12723 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
12724 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
12725 app.adjType = "provider";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012726 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070012727 if (!client.hidden) {
12728 app.hidden = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012729 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070012730 if (client.keeping) {
12731 app.keeping = true;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012732 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -070012733 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
12734 .REASON_PROVIDER_IN_USE;
12735 app.adjSource = client;
12736 app.adjSourceOom = clientAdj;
12737 app.adjTarget = cpr.name;
12738 }
12739 if (client.curSchedGroup == Process.THREAD_GROUP_DEFAULT) {
12740 schedGroup = Process.THREAD_GROUP_DEFAULT;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012741 }
12742 }
12743 // If the provider has external (non-framework) process
12744 // dependencies, ensure that its adjustment is at least
12745 // FOREGROUND_APP_ADJ.
Svetoslav Ganov25872aa2012-02-03 19:19:09 -080012746 if (cpr.hasExternalProcessHandles()) {
Dianne Hackborn7d608422011-08-07 16:24:18 -070012747 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
12748 adj = ProcessList.FOREGROUND_APP_ADJ;
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012749 schedGroup = Process.THREAD_GROUP_DEFAULT;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080012750 app.hidden = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -070012751 app.keeping = true;
Dianne Hackbornde42bb62009-08-05 12:26:15 -070012752 app.adjType = "provider";
Dianne Hackbornb7bb3b32010-06-06 22:47:50 -070012753 app.adjTarget = cpr.name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012754 }
12755 }
12756 }
12757 }
12758
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070012759 if (adj == ProcessList.SERVICE_ADJ) {
12760 if (doingAll) {
12761 app.serviceb = mNewNumServiceProcs > (mNumServiceProcs/3);
12762 mNewNumServiceProcs++;
12763 }
12764 if (app.serviceb) {
12765 adj = ProcessList.SERVICE_B_ADJ;
12766 }
12767 } else {
12768 app.serviceb = false;
12769 }
12770
12771 app.nonStoppingAdj = adj;
12772
12773 if (hasStoppingActivities) {
12774 // Only upgrade adjustment.
12775 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
12776 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12777 app.adjType = "stopping";
12778 }
12779 }
12780
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012781 app.curRawAdj = adj;
12782
Joe Onorato8a9b2202010-02-26 18:56:32 -080012783 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012784 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
12785 if (adj > app.maxAdj) {
12786 adj = app.maxAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070012787 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
Dianne Hackborn09c916b2009-12-08 14:50:51 -080012788 schedGroup = Process.THREAD_GROUP_DEFAULT;
12789 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012790 }
Dianne Hackborn7d608422011-08-07 16:24:18 -070012791 if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070012792 app.keeping = true;
12793 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012794
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012795 if (app.hasAboveClient) {
12796 // If this process has bound to any services with BIND_ABOVE_CLIENT,
12797 // then we need to drop its adjustment to be lower than the service's
12798 // in order to honor the request. We want to drop it by one adjustment
12799 // level... but there is special meaning applied to various levels so
12800 // we will skip some of them.
Dianne Hackborn7d608422011-08-07 16:24:18 -070012801 if (adj < ProcessList.FOREGROUND_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012802 // System process will not get dropped, ever
Dianne Hackborn7d608422011-08-07 16:24:18 -070012803 } else if (adj < ProcessList.VISIBLE_APP_ADJ) {
12804 adj = ProcessList.VISIBLE_APP_ADJ;
12805 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) {
12806 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
12807 } else if (adj < ProcessList.HIDDEN_APP_MIN_ADJ) {
12808 adj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070012809 } else if (adj < ProcessList.HIDDEN_APP_MAX_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012810 adj++;
12811 }
12812 }
12813
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012814 int importance = app.memImportance;
12815 if (importance == 0 || adj != app.curAdj || schedGroup != app.curSchedGroup) {
12816 app.curAdj = adj;
12817 app.curSchedGroup = schedGroup;
12818 if (!interesting) {
12819 // For this reporting, if there is not something explicitly
12820 // interesting in this process then we will push it to the
12821 // background importance.
12822 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12823 } else if (adj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
12824 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12825 } else if (adj >= ProcessList.SERVICE_B_ADJ) {
12826 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12827 } else if (adj >= ProcessList.HOME_APP_ADJ) {
12828 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND;
12829 } else if (adj >= ProcessList.SERVICE_ADJ) {
12830 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE;
12831 } else if (adj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
12832 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_CANT_SAVE_STATE;
12833 } else if (adj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
12834 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE;
12835 } else if (adj >= ProcessList.VISIBLE_APP_ADJ) {
12836 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
12837 } else if (adj >= ProcessList.FOREGROUND_APP_ADJ) {
12838 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
12839 } else {
12840 importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERSISTENT;
12841 }
12842 }
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012843
Dianne Hackborna93c2c12012-05-31 15:29:36 -070012844 int changes = importance != app.memImportance ? ProcessChangeItem.CHANGE_IMPORTANCE : 0;
12845 if (foregroundActivities != app.foregroundActivities) {
12846 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
12847 }
12848 if (changes != 0) {
12849 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Changes in " + app + ": " + changes);
12850 app.memImportance = importance;
12851 app.foregroundActivities = foregroundActivities;
12852 int i = mPendingProcessChanges.size()-1;
12853 ProcessChangeItem item = null;
12854 while (i >= 0) {
12855 item = mPendingProcessChanges.get(i);
12856 if (item.pid == app.pid) {
12857 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Re-using existing item: " + item);
12858 break;
12859 }
12860 i--;
12861 }
12862 if (i < 0) {
12863 // No existing item in pending changes; need a new one.
12864 final int NA = mAvailProcessChanges.size();
12865 if (NA > 0) {
12866 item = mAvailProcessChanges.remove(NA-1);
12867 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Retreiving available item: " + item);
12868 } else {
12869 item = new ProcessChangeItem();
12870 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Allocating new item: " + item);
12871 }
12872 item.changes = 0;
12873 item.pid = app.pid;
12874 item.uid = app.info.uid;
12875 if (mPendingProcessChanges.size() == 0) {
12876 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG,
12877 "*** Enqueueing dispatch processes changed!");
12878 mHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED).sendToTarget();
12879 }
12880 mPendingProcessChanges.add(item);
12881 }
12882 item.changes |= changes;
12883 item.importance = importance;
12884 item.foregroundActivities = foregroundActivities;
12885 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG, "Item "
12886 + Integer.toHexString(System.identityHashCode(item))
12887 + " " + app.toShortString() + ": changes=" + item.changes
12888 + " importance=" + item.importance
12889 + " foreground=" + item.foregroundActivities
12890 + " type=" + app.adjType + " source=" + app.adjSource
12891 + " target=" + app.adjTarget);
Jeff Sharkeyd5cdd592011-05-03 20:27:17 -070012892 }
12893
Dianne Hackbornc68c9132011-07-29 01:25:18 -070012894 return app.curRawAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012895 }
12896
12897 /**
12898 * Ask a given process to GC right now.
12899 */
12900 final void performAppGcLocked(ProcessRecord app) {
12901 try {
12902 app.lastRequestedGc = SystemClock.uptimeMillis();
12903 if (app.thread != null) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012904 if (app.reportLowMemory) {
12905 app.reportLowMemory = false;
12906 app.thread.scheduleLowMemory();
12907 } else {
12908 app.thread.processInBackground();
12909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012910 }
12911 } catch (Exception e) {
12912 // whatever.
12913 }
12914 }
12915
12916 /**
12917 * Returns true if things are idle enough to perform GCs.
12918 */
Josh Bartel7f208742010-02-25 11:01:44 -060012919 private final boolean canGcNowLocked() {
Christopher Tatef46723b2012-01-26 14:19:24 -080012920 boolean processingBroadcasts = false;
12921 for (BroadcastQueue q : mBroadcastQueues) {
12922 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
12923 processingBroadcasts = true;
12924 }
12925 }
12926 return !processingBroadcasts
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070012927 && (mSleeping || (mMainStack.mResumedActivity != null &&
12928 mMainStack.mResumedActivity.idle));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012929 }
12930
12931 /**
12932 * Perform GCs on all processes that are waiting for it, but only
12933 * if things are idle.
12934 */
12935 final void performAppGcsLocked() {
12936 final int N = mProcessesToGc.size();
12937 if (N <= 0) {
12938 return;
12939 }
Josh Bartel7f208742010-02-25 11:01:44 -060012940 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012941 while (mProcessesToGc.size() > 0) {
12942 ProcessRecord proc = mProcessesToGc.remove(0);
Dianne Hackborn7d608422011-08-07 16:24:18 -070012943 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012944 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
12945 <= SystemClock.uptimeMillis()) {
12946 // To avoid spamming the system, we will GC processes one
12947 // at a time, waiting a few seconds between each.
12948 performAppGcLocked(proc);
12949 scheduleAppGcsLocked();
12950 return;
12951 } else {
12952 // It hasn't been long enough since we last GCed this
12953 // process... put it in the list to wait for its time.
12954 addProcessToGcListLocked(proc);
12955 break;
12956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012957 }
12958 }
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012959
12960 scheduleAppGcsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012961 }
12962 }
12963
12964 /**
12965 * If all looks good, perform GCs on all processes waiting for them.
12966 */
12967 final void performAppGcsIfAppropriateLocked() {
Josh Bartel7f208742010-02-25 11:01:44 -060012968 if (canGcNowLocked()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012969 performAppGcsLocked();
12970 return;
12971 }
12972 // Still not idle, wait some more.
12973 scheduleAppGcsLocked();
12974 }
12975
12976 /**
12977 * Schedule the execution of all pending app GCs.
12978 */
12979 final void scheduleAppGcsLocked() {
12980 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012981
12982 if (mProcessesToGc.size() > 0) {
12983 // Schedule a GC for the time to the next process.
12984 ProcessRecord proc = mProcessesToGc.get(0);
12985 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
12986
Dianne Hackbornce86ba82011-07-13 19:33:41 -070012987 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
Dianne Hackbornfd12af42009-08-27 00:44:33 -070012988 long now = SystemClock.uptimeMillis();
12989 if (when < (now+GC_TIMEOUT)) {
12990 when = now + GC_TIMEOUT;
12991 }
12992 mHandler.sendMessageAtTime(msg, when);
12993 }
12994 }
12995
12996 /**
12997 * Add a process to the array of processes waiting to be GCed. Keeps the
12998 * list in sorted order by the last GC time. The process can't already be
12999 * on the list.
13000 */
13001 final void addProcessToGcListLocked(ProcessRecord proc) {
13002 boolean added = false;
13003 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
13004 if (mProcessesToGc.get(i).lastRequestedGc <
13005 proc.lastRequestedGc) {
13006 added = true;
13007 mProcessesToGc.add(i+1, proc);
13008 break;
13009 }
13010 }
13011 if (!added) {
13012 mProcessesToGc.add(0, proc);
13013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013014 }
13015
13016 /**
13017 * Set up to ask a process to GC itself. This will either do it
13018 * immediately, or put it on the list of processes to gc the next
13019 * time things are idle.
13020 */
13021 final void scheduleAppGcLocked(ProcessRecord app) {
13022 long now = SystemClock.uptimeMillis();
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013023 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013024 return;
13025 }
13026 if (!mProcessesToGc.contains(app)) {
Dianne Hackbornfd12af42009-08-27 00:44:33 -070013027 addProcessToGcListLocked(app);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013028 scheduleAppGcsLocked();
13029 }
13030 }
13031
Dianne Hackborn287952c2010-09-22 22:34:31 -070013032 final void checkExcessivePowerUsageLocked(boolean doKills) {
13033 updateCpuStatsNow();
13034
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013035 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013036 boolean doWakeKills = doKills;
13037 boolean doCpuKills = doKills;
13038 if (mLastPowerCheckRealtime == 0) {
13039 doWakeKills = false;
13040 }
13041 if (mLastPowerCheckUptime == 0) {
13042 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013043 }
13044 if (stats.isScreenOn()) {
Dianne Hackborn287952c2010-09-22 22:34:31 -070013045 doWakeKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013046 }
13047 final long curRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn287952c2010-09-22 22:34:31 -070013048 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
13049 final long curUptime = SystemClock.uptimeMillis();
13050 final long uptimeSince = curUptime - mLastPowerCheckUptime;
13051 mLastPowerCheckRealtime = curRealtime;
13052 mLastPowerCheckUptime = curUptime;
13053 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
13054 doWakeKills = false;
13055 }
13056 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
13057 doCpuKills = false;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013058 }
13059 int i = mLruProcesses.size();
13060 while (i > 0) {
13061 i--;
13062 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013063 if (!app.keeping) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013064 long wtime;
13065 synchronized (stats) {
13066 wtime = stats.getProcessWakeTime(app.info.uid,
13067 app.pid, curRealtime);
13068 }
Dianne Hackborn287952c2010-09-22 22:34:31 -070013069 long wtimeUsed = wtime - app.lastWakeTime;
13070 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
13071 if (DEBUG_POWER) {
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013072 StringBuilder sb = new StringBuilder(128);
13073 sb.append("Wake for ");
13074 app.toShortString(sb);
13075 sb.append(": over ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013076 TimeUtils.formatDuration(realtimeSince, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013077 sb.append(" used ");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013078 TimeUtils.formatDuration(wtimeUsed, sb);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013079 sb.append(" (");
Dianne Hackborn287952c2010-09-22 22:34:31 -070013080 sb.append((wtimeUsed*100)/realtimeSince);
13081 sb.append("%)");
13082 Slog.i(TAG, sb.toString());
13083 sb.setLength(0);
13084 sb.append("CPU for ");
13085 app.toShortString(sb);
13086 sb.append(": over ");
13087 TimeUtils.formatDuration(uptimeSince, sb);
13088 sb.append(" used ");
13089 TimeUtils.formatDuration(cputimeUsed, sb);
13090 sb.append(" (");
13091 sb.append((cputimeUsed*100)/uptimeSince);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -070013092 sb.append("%)");
13093 Slog.i(TAG, sb.toString());
13094 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013095 // If a process has held a wake lock for more
13096 // than 50% of the time during this period,
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013097 // that sounds bad. Kill!
Dianne Hackborn287952c2010-09-22 22:34:31 -070013098 if (doWakeKills && realtimeSince > 0
13099 && ((wtimeUsed*100)/realtimeSince) >= 50) {
13100 synchronized (stats) {
13101 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
13102 realtimeSince, wtimeUsed);
13103 }
13104 Slog.w(TAG, "Excessive wake lock in " + app.processName
13105 + " (pid " + app.pid + "): held " + wtimeUsed
13106 + " during " + realtimeSince);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013107 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13108 app.processName, app.setAdj, "excessive wake lock");
13109 Process.killProcessQuiet(app.pid);
Dianne Hackborn287952c2010-09-22 22:34:31 -070013110 } else if (doCpuKills && uptimeSince > 0
13111 && ((cputimeUsed*100)/uptimeSince) >= 50) {
13112 synchronized (stats) {
13113 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
13114 uptimeSince, cputimeUsed);
13115 }
13116 Slog.w(TAG, "Excessive CPU in " + app.processName
13117 + " (pid " + app.pid + "): used " + cputimeUsed
13118 + " during " + uptimeSince);
13119 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13120 app.processName, app.setAdj, "excessive cpu");
13121 Process.killProcessQuiet(app.pid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013122 } else {
13123 app.lastWakeTime = wtime;
Dianne Hackborn287952c2010-09-22 22:34:31 -070013124 app.lastCpuTime = app.curCpuTime;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013125 }
13126 }
13127 }
13128 }
13129
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013130 private final boolean updateOomAdjLocked(ProcessRecord app, int hiddenAdj,
13131 int emptyAdj, ProcessRecord TOP_APP, boolean doingAll) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013132 app.hiddenAdj = hiddenAdj;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013133 app.emptyAdj = emptyAdj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013134
13135 if (app.thread == null) {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013136 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013137 }
13138
Dianne Hackborn287952c2010-09-22 22:34:31 -070013139 final boolean wasKeeping = app.keeping;
13140
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013141 boolean success = true;
13142
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013143 computeOomAdjLocked(app, hiddenAdj, emptyAdj, TOP_APP, false, doingAll);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013144
Jeff Brown10e89712011-07-08 18:52:57 -070013145 if (app.curRawAdj != app.setRawAdj) {
Jeff Brown10e89712011-07-08 18:52:57 -070013146 if (wasKeeping && !app.keeping) {
13147 // This app is no longer something we want to keep. Note
13148 // its current wake lock time to later know to kill it if
13149 // it is not behaving well.
13150 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
13151 synchronized (stats) {
13152 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
13153 app.pid, SystemClock.elapsedRealtime());
13154 }
13155 app.lastCpuTime = app.curCpuTime;
13156 }
13157
13158 app.setRawAdj = app.curRawAdj;
13159 }
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013160
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013161 if (app.curAdj != app.setAdj) {
13162 if (Process.setOomAdj(app.pid, app.curAdj)) {
Dianne Hackbornbbb09ac2011-11-30 11:31:29 -080013163 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013164 TAG, "Set " + app.pid + " " + app.processName +
13165 " adj " + app.curAdj + ": " + app.adjType);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013166 app.setAdj = app.curAdj;
Jeff Brown10e89712011-07-08 18:52:57 -070013167 } else {
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013168 success = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013169 Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
Jeff Brown10e89712011-07-08 18:52:57 -070013170 }
13171 }
13172 if (app.setSchedGroup != app.curSchedGroup) {
13173 app.setSchedGroup = app.curSchedGroup;
13174 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG,
13175 "Setting process group of " + app.processName
13176 + " to " + app.curSchedGroup);
13177 if (app.waitingToKill != null &&
13178 app.setSchedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE) {
13179 Slog.i(TAG, "Killing " + app.toShortString() + ": " + app.waitingToKill);
13180 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13181 app.processName, app.setAdj, app.waitingToKill);
Dianne Hackborn45a25bc2012-06-28 13:49:17 -070013182 app.killedBackground = true;
Jeff Brown10e89712011-07-08 18:52:57 -070013183 Process.killProcessQuiet(app.pid);
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013184 success = false;
Jeff Brown10e89712011-07-08 18:52:57 -070013185 } else {
13186 if (true) {
13187 long oldId = Binder.clearCallingIdentity();
13188 try {
13189 Process.setProcessGroup(app.pid, app.curSchedGroup);
13190 } catch (Exception e) {
13191 Slog.w(TAG, "Failed setting process group of " + app.pid
13192 + " to " + app.curSchedGroup);
13193 e.printStackTrace();
13194 } finally {
13195 Binder.restoreCallingIdentity(oldId);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -070013196 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013197 } else {
Jeff Brown10e89712011-07-08 18:52:57 -070013198 if (app.thread != null) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013199 try {
Jeff Brown10e89712011-07-08 18:52:57 -070013200 app.thread.setSchedulingGroup(app.curSchedGroup);
13201 } catch (RemoteException e) {
Dianne Hackborn06de2ea2009-05-21 12:56:43 -070013202 }
13203 }
13204 }
13205 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013206 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013207 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013208 }
13209
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013210 private final ActivityRecord resumedAppLocked() {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013211 ActivityRecord resumedActivity = mMainStack.mResumedActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013212 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn621e2fe2012-02-16 17:07:33 -080013213 resumedActivity = mMainStack.mPausingActivity;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013214 if (resumedActivity == null || resumedActivity.app == null) {
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013215 resumedActivity = mMainStack.topRunningActivityLocked(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013216 }
13217 }
13218 return resumedActivity;
13219 }
13220
Dianne Hackborn599db5c2012-08-03 19:28:48 -070013221 final boolean updateOomAdjLocked(ProcessRecord app) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013222 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013223 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13224 int curAdj = app.curAdj;
Dianne Hackborn7d608422011-08-07 16:24:18 -070013225 final boolean wasHidden = curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13226 && curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013227
13228 mAdjSeq++;
13229
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013230 boolean success = updateOomAdjLocked(app, app.hiddenAdj, app.emptyAdj,
13231 TOP_APP, false);
Dianne Hackborn7d608422011-08-07 16:24:18 -070013232 final boolean nowHidden = app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ
13233 && app.curAdj <= ProcessList.HIDDEN_APP_MAX_ADJ;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013234 if (nowHidden != wasHidden) {
13235 // Changed to/from hidden state, so apps after it in the LRU
13236 // list may also be changed.
13237 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013238 }
Dianne Hackborn295e3c22011-08-25 13:19:08 -070013239 return success;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013240 }
13241
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013242 final void updateOomAdjLocked() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -070013243 final ActivityRecord TOP_ACT = resumedAppLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013244 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
13245
13246 if (false) {
13247 RuntimeException e = new RuntimeException();
13248 e.fillInStackTrace();
Joe Onorato8a9b2202010-02-26 18:56:32 -080013249 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013250 }
13251
13252 mAdjSeq++;
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013253 mNewNumServiceProcs = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013254
Dianne Hackborn5ce7d282010-02-12 19:30:02 -080013255 // Let's determine how many processes we have running vs.
13256 // how many slots we have for background processes; we may want
13257 // to put multiple processes in a slot of there are enough of
13258 // them.
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013259 int numSlots = (ProcessList.HIDDEN_APP_MAX_ADJ
13260 - ProcessList.HIDDEN_APP_MIN_ADJ + 1) / 2;
13261 int emptyFactor = (mLruProcesses.size()-mNumNonHiddenProcs-mNumHiddenProcs)/numSlots;
13262 if (emptyFactor < 1) emptyFactor = 1;
13263 int hiddenFactor = (mNumHiddenProcs > 0 ? mNumHiddenProcs : 1)/numSlots;
13264 if (hiddenFactor < 1) hiddenFactor = 1;
13265 int stepHidden = 0;
13266 int stepEmpty = 0;
13267 final int emptyProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
13268 final int hiddenProcessLimit = mProcessLimit > 1 ? mProcessLimit / 2 : mProcessLimit;
Dianne Hackborn8633e682010-04-22 16:03:41 -070013269 int numHidden = 0;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013270 int numEmpty = 0;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013271 int numTrimming = 0;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013272
13273 mNumNonHiddenProcs = 0;
13274 mNumHiddenProcs = 0;
13275
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013276 // First update the OOM adjustment for each of the
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013277 // application processes based on their current state.
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013278 int i = mLruProcesses.size();
Dianne Hackborn7d608422011-08-07 16:24:18 -070013279 int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013280 int nextHiddenAdj = curHiddenAdj+1;
13281 int curEmptyAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
13282 int nextEmptyAdj = curEmptyAdj+2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013283 while (i > 0) {
13284 i--;
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013285 ProcessRecord app = mLruProcesses.get(i);
Joe Onorato8a9b2202010-02-26 18:56:32 -080013286 //Slog.i(TAG, "OOM " + app + ": cur hidden=" + curHiddenAdj);
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013287 updateOomAdjLocked(app, curHiddenAdj, curEmptyAdj, TOP_APP, true);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013288 if (!app.killedBackground) {
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013289 if (app.curRawAdj == curHiddenAdj && app.hasActivities) {
13290 // This process was assigned as a hidden process... step the
13291 // hidden level.
13292 mNumHiddenProcs++;
13293 if (curHiddenAdj != nextHiddenAdj) {
13294 stepHidden++;
13295 if (stepHidden >= hiddenFactor) {
13296 stepHidden = 0;
13297 curHiddenAdj = nextHiddenAdj;
13298 nextHiddenAdj += 2;
13299 if (nextHiddenAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13300 nextHiddenAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13301 }
13302 }
13303 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013304 numHidden++;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013305 if (numHidden > hiddenProcessLimit) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013306 Slog.i(TAG, "No longer want " + app.processName
13307 + " (pid " + app.pid + "): hidden #" + numHidden);
13308 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13309 app.processName, app.setAdj, "too many background");
13310 app.killedBackground = true;
13311 Process.killProcessQuiet(app.pid);
Dianne Hackborn8633e682010-04-22 16:03:41 -070013312 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013313 } else {
13314 if (app.curRawAdj == curEmptyAdj || app.curRawAdj == curHiddenAdj) {
13315 // This process was assigned as an empty process... step the
13316 // empty level.
13317 if (curEmptyAdj != nextEmptyAdj) {
13318 stepEmpty++;
13319 if (stepEmpty >= emptyFactor) {
13320 stepEmpty = 0;
13321 curEmptyAdj = nextEmptyAdj;
13322 nextEmptyAdj += 2;
13323 if (nextEmptyAdj > ProcessList.HIDDEN_APP_MAX_ADJ) {
13324 nextEmptyAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
13325 }
13326 }
13327 }
13328 } else if (app.curRawAdj < ProcessList.HIDDEN_APP_MIN_ADJ) {
13329 mNumNonHiddenProcs++;
13330 }
13331 if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
13332 numEmpty++;
13333 if (numEmpty > emptyProcessLimit) {
13334 Slog.i(TAG, "No longer want " + app.processName
13335 + " (pid " + app.pid + "): empty #" + numEmpty);
13336 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13337 app.processName, app.setAdj, "too many background");
13338 app.killedBackground = true;
13339 Process.killProcessQuiet(app.pid);
13340 }
13341 }
Dianne Hackborn8633e682010-04-22 16:03:41 -070013342 }
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013343 if (app.isolated && app.services.size() <= 0) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013344 // If this is an isolated process, and there are no
13345 // services running in it, then the process is no longer
13346 // needed. We agressively kill these because we can by
13347 // definition not re-use the same process again, and it is
13348 // good to avoid having whatever code was running in them
13349 // left sitting around after no longer needed.
13350 Slog.i(TAG, "Isolated process " + app.processName
13351 + " (pid " + app.pid + ") no longer needed");
13352 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13353 app.processName, app.setAdj, "isolated not needed");
13354 app.killedBackground = true;
13355 Process.killProcessQuiet(app.pid);
13356 }
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013357 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13358 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
13359 && !app.killedBackground) {
13360 numTrimming++;
13361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013362 }
13363 }
13364
Dianne Hackborne02c88a2011-10-28 13:58:15 -070013365 mNumServiceProcs = mNewNumServiceProcs;
13366
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013367 // Now determine the memory trimming level of background processes.
13368 // Unfortunately we need to start at the back of the list to do this
13369 // properly. We only do this if the number of background apps we
13370 // are managing to keep around is less than half the maximum we desire;
13371 // if we are keeping a good number around, we'll let them use whatever
13372 // memory they want.
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013373 if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/4)
13374 && numEmpty <= (ProcessList.MAX_HIDDEN_APPS/4)) {
13375 final int numHiddenAndEmpty = numHidden + numEmpty;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013376 final int N = mLruProcesses.size();
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013377 int factor = numTrimming/3;
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080013378 int minFactor = 2;
13379 if (mHomeProcess != null) minFactor++;
13380 if (mPreviousProcess != null) minFactor++;
13381 if (factor < minFactor) factor = minFactor;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013382 int step = 0;
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013383 int fgTrimLevel;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013384 if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/5)) {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013385 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
Dianne Hackbornee7621c2012-08-13 16:42:18 -070013386 } else if (numHiddenAndEmpty <= (ProcessList.MAX_HIDDEN_APPS/3)) {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013387 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
13388 } else {
13389 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
13390 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013391 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013392 for (i=0; i<N; i++) {
13393 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013394 if (app.nonStoppingAdj >= ProcessList.HOME_APP_ADJ
13395 && app.nonStoppingAdj != ProcessList.SERVICE_B_ADJ
Dianne Hackbornd8c98fe2011-11-15 11:29:38 -080013396 && !app.killedBackground) {
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013397 if (app.trimMemoryLevel < curLevel && app.thread != null) {
13398 try {
13399 app.thread.scheduleTrimMemory(curLevel);
13400 } catch (RemoteException e) {
13401 }
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080013402 if (false) {
13403 // For now we won't do this; our memory trimming seems
13404 // to be good enough at this point that destroying
13405 // activities causes more harm than good.
13406 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
13407 && app != mHomeProcess && app != mPreviousProcess) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070013408 // Need to do this on its own message because the stack may not
13409 // be in a consistent state at this point.
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080013410 // For these apps we will also finish their activities
13411 // to help them free memory.
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070013412 mMainStack.scheduleDestroyActivities(app, false, "trim");
Dianne Hackborn77eaaf02011-12-05 18:05:31 -080013413 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013414 }
13415 }
13416 app.trimMemoryLevel = curLevel;
13417 step++;
13418 if (step >= factor) {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013419 step = 0;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013420 switch (curLevel) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013421 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
13422 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013423 break;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013424 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
13425 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013426 break;
13427 }
13428 }
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013429 } else if (app.nonStoppingAdj == ProcessList.HEAVY_WEIGHT_APP_ADJ) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013430 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013431 && app.thread != null) {
13432 try {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013433 app.thread.scheduleTrimMemory(
13434 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013435 } catch (RemoteException e) {
13436 }
13437 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013438 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013439 } else {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013440 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013441 && app.pendingUiClean) {
13442 // If this application is now in the background and it
13443 // had done UI, then give it the special trim level to
13444 // have it free UI resources.
13445 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
13446 if (app.trimMemoryLevel < level && app.thread != null) {
13447 try {
13448 app.thread.scheduleTrimMemory(level);
13449 } catch (RemoteException e) {
13450 }
13451 }
13452 app.pendingUiClean = false;
13453 }
13454 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013455 try {
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013456 app.thread.scheduleTrimMemory(fgTrimLevel);
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013457 } catch (RemoteException e) {
13458 }
13459 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013460 app.trimMemoryLevel = fgTrimLevel;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013461 }
13462 }
13463 } else {
13464 final int N = mLruProcesses.size();
13465 for (i=0; i<N; i++) {
13466 ProcessRecord app = mLruProcesses.get(i);
Dianne Hackborn162bc0e2012-04-09 14:06:16 -070013467 if ((app.nonStoppingAdj > ProcessList.VISIBLE_APP_ADJ || app.systemNoUi)
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013468 && app.pendingUiClean) {
13469 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
13470 && app.thread != null) {
13471 try {
13472 app.thread.scheduleTrimMemory(
13473 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
13474 } catch (RemoteException e) {
13475 }
13476 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013477 app.pendingUiClean = false;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070013478 }
Dianne Hackborn27ff9132012-03-06 14:57:58 -080013479 app.trimMemoryLevel = 0;
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013480 }
13481 }
13482
13483 if (mAlwaysFinishActivities) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -070013484 // Need to do this on its own message because the stack may not
13485 // be in a consistent state at this point.
13486 mMainStack.scheduleDestroyActivities(null, false, "always-finish");
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013487 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013488 }
13489
Dianne Hackborn50dc3bc2010-06-25 10:05:59 -070013490 final void trimApplications() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013491 synchronized (this) {
13492 int i;
13493
13494 // First remove any unused application processes whose package
13495 // has been removed.
13496 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
13497 final ProcessRecord app = mRemovedProcesses.get(i);
13498 if (app.activities.size() == 0
13499 && app.curReceiver == null && app.services.size() == 0) {
Joe Onorato8a9b2202010-02-26 18:56:32 -080013500 Slog.i(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013501 TAG, "Exiting empty application process "
13502 + app.processName + " ("
13503 + (app.thread != null ? app.thread.asBinder() : null)
13504 + ")\n");
13505 if (app.pid > 0 && app.pid != MY_PID) {
Dianne Hackborn0c5001d2011-04-12 18:16:08 -070013506 EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
13507 app.processName, app.setAdj, "empty");
13508 Process.killProcessQuiet(app.pid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013509 } else {
13510 try {
13511 app.thread.scheduleExit();
13512 } catch (Exception e) {
13513 // Ignore exceptions.
13514 }
13515 }
Dianne Hackborn130b0d22011-07-26 22:07:48 -070013516 cleanUpApplicationRecordLocked(app, false, true, -1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013517 mRemovedProcesses.remove(i);
13518
13519 if (app.persistent) {
13520 if (app.persistent) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -080013521 addAppLocked(app.info, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013522 }
13523 }
13524 }
13525 }
13526
Dianne Hackbornce86ba82011-07-13 19:33:41 -070013527 // Now update the oom adj for all processes.
13528 updateOomAdjLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013529 }
13530 }
13531
13532 /** This method sends the specified signal to each of the persistent apps */
13533 public void signalPersistentProcesses(int sig) throws RemoteException {
13534 if (sig != Process.SIGNAL_USR1) {
13535 throw new SecurityException("Only SIGNAL_USR1 is allowed");
13536 }
13537
13538 synchronized (this) {
13539 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
13540 != PackageManager.PERMISSION_GRANTED) {
13541 throw new SecurityException("Requires permission "
13542 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
13543 }
13544
Dianne Hackborndd71fc82009-12-16 19:24:32 -080013545 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13546 ProcessRecord r = mLruProcesses.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013547 if (r.thread != null && r.persistent) {
13548 Process.sendSignal(r.pid, sig);
13549 }
13550 }
13551 }
13552 }
13553
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013554 private void stopProfilerLocked(ProcessRecord proc, String path, int profileType) {
13555 if (proc == null || proc == mProfileProc) {
13556 proc = mProfileProc;
13557 path = mProfileFile;
13558 profileType = mProfileType;
13559 clearProfilerLocked();
13560 }
13561 if (proc == null) {
13562 return;
13563 }
13564 try {
13565 proc.thread.profilerControl(false, path, null, profileType);
13566 } catch (RemoteException e) {
13567 throw new IllegalStateException("Process disappeared");
13568 }
13569 }
13570
13571 private void clearProfilerLocked() {
13572 if (mProfileFd != null) {
13573 try {
13574 mProfileFd.close();
13575 } catch (IOException e) {
13576 }
13577 }
13578 mProfileApp = null;
13579 mProfileProc = null;
13580 mProfileFile = null;
13581 mProfileType = 0;
13582 mAutoStopProfiler = false;
13583 }
13584
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013585 public boolean profileControl(String process, boolean start,
Romain Guy7eabe552011-07-21 14:56:34 -070013586 String path, ParcelFileDescriptor fd, int profileType) throws RemoteException {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013587
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013588 try {
13589 synchronized (this) {
13590 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13591 // its own permission.
13592 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13593 != PackageManager.PERMISSION_GRANTED) {
13594 throw new SecurityException("Requires permission "
13595 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013596 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013597
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013598 if (start && fd == null) {
13599 throw new IllegalArgumentException("null fd");
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013600 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013601
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013602 ProcessRecord proc = null;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013603 if (process != null) {
13604 try {
13605 int pid = Integer.parseInt(process);
13606 synchronized (mPidsSelfLocked) {
13607 proc = mPidsSelfLocked.get(pid);
13608 }
13609 } catch (NumberFormatException e) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013610 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013611
13612 if (proc == null) {
13613 HashMap<String, SparseArray<ProcessRecord>> all
13614 = mProcessNames.getMap();
13615 SparseArray<ProcessRecord> procs = all.get(process);
13616 if (procs != null && procs.size() > 0) {
13617 proc = procs.valueAt(0);
13618 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013619 }
13620 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013621
13622 if (start && (proc == null || proc.thread == null)) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013623 throw new IllegalArgumentException("Unknown process: " + process);
13624 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013625
13626 if (start) {
13627 stopProfilerLocked(null, null, 0);
13628 setProfileApp(proc.info, proc.processName, path, fd, false);
13629 mProfileProc = proc;
13630 mProfileType = profileType;
13631 try {
13632 fd = fd.dup();
13633 } catch (IOException e) {
13634 fd = null;
13635 }
13636 proc.thread.profilerControl(start, path, fd, profileType);
13637 fd = null;
13638 mProfileFd = null;
13639 } else {
13640 stopProfilerLocked(proc, path, profileType);
13641 if (fd != null) {
13642 try {
13643 fd.close();
13644 } catch (IOException e) {
13645 }
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013646 }
13647 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -070013648
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013649 return true;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070013650 }
13651 } catch (RemoteException e) {
13652 throw new IllegalStateException("Process disappeared");
13653 } finally {
13654 if (fd != null) {
13655 try {
13656 fd.close();
13657 } catch (IOException e) {
13658 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -080013659 }
13660 }
13661 }
Andy McFadden824c5102010-07-09 16:26:57 -070013662
13663 public boolean dumpHeap(String process, boolean managed,
13664 String path, ParcelFileDescriptor fd) throws RemoteException {
13665
13666 try {
13667 synchronized (this) {
13668 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
13669 // its own permission (same as profileControl).
13670 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13671 != PackageManager.PERMISSION_GRANTED) {
13672 throw new SecurityException("Requires permission "
13673 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13674 }
13675
13676 if (fd == null) {
13677 throw new IllegalArgumentException("null fd");
13678 }
13679
13680 ProcessRecord proc = null;
13681 try {
13682 int pid = Integer.parseInt(process);
13683 synchronized (mPidsSelfLocked) {
13684 proc = mPidsSelfLocked.get(pid);
13685 }
13686 } catch (NumberFormatException e) {
13687 }
13688
13689 if (proc == null) {
13690 HashMap<String, SparseArray<ProcessRecord>> all
13691 = mProcessNames.getMap();
13692 SparseArray<ProcessRecord> procs = all.get(process);
13693 if (procs != null && procs.size() > 0) {
13694 proc = procs.valueAt(0);
13695 }
13696 }
13697
13698 if (proc == null || proc.thread == null) {
13699 throw new IllegalArgumentException("Unknown process: " + process);
13700 }
13701
Dianne Hackbornf02e57b2011-03-01 22:21:04 -080013702 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
13703 if (!isDebuggable) {
Andy McFadden824c5102010-07-09 16:26:57 -070013704 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
13705 throw new SecurityException("Process not debuggable: " + proc);
13706 }
13707 }
13708
13709 proc.thread.dumpHeap(managed, path, fd);
13710 fd = null;
13711 return true;
13712 }
13713 } catch (RemoteException e) {
13714 throw new IllegalStateException("Process disappeared");
13715 } finally {
13716 if (fd != null) {
13717 try {
13718 fd.close();
13719 } catch (IOException e) {
13720 }
13721 }
13722 }
13723 }
13724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013725 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
13726 public void monitor() {
13727 synchronized (this) { }
13728 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013729
Dianne Hackborna573f6a2012-02-09 16:12:18 -080013730 void onCoreSettingsChange(Bundle settings) {
Svetoslav Ganov54d068e2011-03-02 12:58:40 -080013731 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13732 ProcessRecord processRecord = mLruProcesses.get(i);
13733 try {
13734 if (processRecord.thread != null) {
13735 processRecord.thread.setCoreSettings(settings);
13736 }
13737 } catch (RemoteException re) {
13738 /* ignore */
13739 }
13740 }
13741 }
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013742
13743 // Multi-user methods
13744
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013745 @Override
Amith Yamasani742a6712011-05-04 14:49:28 -070013746 public boolean switchUser(int userId) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013747 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13748 != PackageManager.PERMISSION_GRANTED) {
13749 String msg = "Permission Denial: switchUser() from pid="
13750 + Binder.getCallingPid()
13751 + ", uid=" + Binder.getCallingUid()
13752 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13753 Slog.w(TAG, msg);
13754 throw new SecurityException(msg);
Amith Yamasani742a6712011-05-04 14:49:28 -070013755 }
Amith Yamasani742a6712011-05-04 14:49:28 -070013756 synchronized (this) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013757 if (mCurrentUserId == userId) {
13758 return true;
13759 }
13760
13761 // If the user we are switching to is not currently started, then
13762 // we need to start it now.
13763 if (mStartedUsers.get(userId) == null) {
13764 mStartedUsers.put(userId, new UserStartedState(new UserHandle(userId), false));
Amith Yamasani742a6712011-05-04 14:49:28 -070013765 }
13766
13767 mCurrentUserId = userId;
13768 boolean haveActivities = mMainStack.switchUser(userId);
13769 if (!haveActivities) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013770 startHomeActivityLocked(userId, mStartedUsers.get(userId));
Amith Yamasani742a6712011-05-04 14:49:28 -070013771 }
Amith Yamasani37ce3a82012-02-06 12:04:42 -080013772 }
Amith Yamasani13593602012-03-22 16:16:17 -070013773
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013774 long ident = Binder.clearCallingIdentity();
13775 try {
13776 // Inform of user switch
13777 Intent addedIntent = new Intent(Intent.ACTION_USER_SWITCHED);
13778 addedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070013779 mContext.sendBroadcastAsUser(addedIntent, UserHandle.ALL,
13780 android.Manifest.permission.MANAGE_USERS);
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013781 } finally {
13782 Binder.restoreCallingIdentity(ident);
13783 }
Amith Yamasani13593602012-03-22 16:16:17 -070013784
Amith Yamasani4b2e9342011-03-31 12:38:53 -070013785 return true;
13786 }
Amith Yamasani742a6712011-05-04 14:49:28 -070013787
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013788 void finishUserSwitch(UserStartedState uss) {
13789 synchronized (this) {
13790 if (uss.mState == UserStartedState.STATE_BOOTING
13791 && mStartedUsers.get(uss.mHandle.getIdentifier()) == uss) {
13792 uss.mState = UserStartedState.STATE_RUNNING;
Dianne Hackborn41203752012-08-31 14:05:51 -070013793 final int userId = uss.mHandle.getIdentifier();
13794 Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED, null);
13795 intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
13796 broadcastIntentLocked(null, null, intent,
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013797 null, null, 0, null, null,
13798 android.Manifest.permission.RECEIVE_BOOT_COMPLETED,
Dianne Hackborn41203752012-08-31 14:05:51 -070013799 false, false, MY_PID, Process.SYSTEM_UID, userId);
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013800 }
Amith Yamasani52f1d752012-03-28 18:19:29 -070013801 }
Amith Yamasani52f1d752012-03-28 18:19:29 -070013802 }
13803
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013804 @Override
13805 public int stopUser(final int userId, final IStopUserCallback callback) {
13806 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13807 != PackageManager.PERMISSION_GRANTED) {
13808 String msg = "Permission Denial: switchUser() from pid="
13809 + Binder.getCallingPid()
13810 + ", uid=" + Binder.getCallingUid()
13811 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13812 Slog.w(TAG, msg);
13813 throw new SecurityException(msg);
13814 }
13815 if (userId <= 0) {
13816 throw new IllegalArgumentException("Can't stop primary user " + userId);
13817 }
Amith Yamasani13593602012-03-22 16:16:17 -070013818 synchronized (this) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013819 if (mCurrentUserId == userId) {
13820 return ActivityManager.USER_OP_IS_CURRENT;
13821 }
13822
13823 final UserStartedState uss = mStartedUsers.get(userId);
13824 if (uss == null) {
13825 // User is not started, nothing to do... but we do need to
13826 // callback if requested.
13827 if (callback != null) {
13828 mHandler.post(new Runnable() {
13829 @Override
13830 public void run() {
13831 try {
13832 callback.userStopped(userId);
13833 } catch (RemoteException e) {
13834 }
13835 }
13836 });
13837 }
13838 return ActivityManager.USER_OP_SUCCESS;
13839 }
13840
13841 if (callback != null) {
13842 uss.mStopCallbacks.add(callback);
13843 }
13844
13845 if (uss.mState != UserStartedState.STATE_STOPPING) {
13846 uss.mState = UserStartedState.STATE_STOPPING;
13847
13848 long ident = Binder.clearCallingIdentity();
13849 try {
13850 // Inform of user switch
13851 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13852 final IIntentReceiver resultReceiver = new IIntentReceiver.Stub() {
13853 @Override
13854 public void performReceive(Intent intent, int resultCode, String data,
Dianne Hackborn20e80982012-08-31 19:00:44 -070013855 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013856 finishUserStop(uss);
13857 }
13858 };
13859 broadcastIntentLocked(null, null, intent,
13860 null, resultReceiver, 0, null, null, null,
13861 true, false, MY_PID, Process.SYSTEM_UID, userId);
13862 } finally {
13863 Binder.restoreCallingIdentity(ident);
Amith Yamasani13593602012-03-22 16:16:17 -070013864 }
13865 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013866 }
Amith Yamasani13593602012-03-22 16:16:17 -070013867
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013868 return ActivityManager.USER_OP_SUCCESS;
13869 }
13870
13871 void finishUserStop(UserStartedState uss) {
13872 final int userId = uss.mHandle.getIdentifier();
13873 boolean stopped;
13874 ArrayList<IStopUserCallback> callbacks;
13875 synchronized (this) {
13876 callbacks = new ArrayList<IStopUserCallback>(uss.mStopCallbacks);
13877 if (uss.mState != UserStartedState.STATE_STOPPING
13878 || mStartedUsers.get(userId) != uss) {
13879 stopped = false;
13880 } else {
13881 stopped = true;
13882 // User can no longer run.
13883 mStartedUsers.remove(userId);
13884
13885 // Clean up all state and processes associated with the user.
13886 // Kill all the processes for the user.
13887 forceStopUserLocked(userId);
Amith Yamasani13593602012-03-22 16:16:17 -070013888 }
13889 }
Dianne Hackborn80a4af22012-08-27 19:18:31 -070013890
13891 for (int i=0; i<callbacks.size(); i++) {
13892 try {
13893 if (stopped) callbacks.get(i).userStopped(userId);
13894 else callbacks.get(i).userStopAborted(userId);
13895 } catch (RemoteException e) {
13896 }
13897 }
13898 }
13899
13900 @Override
13901 public UserInfo getCurrentUser() {
13902 if (checkCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
13903 != PackageManager.PERMISSION_GRANTED) {
13904 String msg = "Permission Denial: getCurrentUser() from pid="
13905 + Binder.getCallingPid()
13906 + ", uid=" + Binder.getCallingUid()
13907 + " requires " + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
13908 Slog.w(TAG, msg);
13909 throw new SecurityException(msg);
13910 }
13911 synchronized (this) {
13912 return getUserManager().getUserInfo(mCurrentUserId);
13913 }
Amith Yamasani13593602012-03-22 16:16:17 -070013914 }
13915
Amith Yamasani742a6712011-05-04 14:49:28 -070013916 private boolean userExists(int userId) {
Amith Yamasani258848d2012-08-10 17:06:33 -070013917 UserInfo user = getUserManager().getUserInfo(userId);
13918 return user != null;
13919 }
Amith Yamasani742a6712011-05-04 14:49:28 -070013920
Amith Yamasani258848d2012-08-10 17:06:33 -070013921 UserManager getUserManager() {
13922 if (mUserManager == null) {
13923 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
13924 }
13925 return mUserManager;
Amith Yamasani742a6712011-05-04 14:49:28 -070013926 }
13927
Amith Yamasani37ce3a82012-02-06 12:04:42 -080013928 private void checkValidCaller(int uid, int userId) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070013929 if (UserHandle.getUserId(uid) == userId || uid == Process.SYSTEM_UID || uid == 0) return;
Amith Yamasani37ce3a82012-02-06 12:04:42 -080013930
13931 throw new SecurityException("Caller uid=" + uid
13932 + " is not privileged to communicate with user=" + userId);
13933 }
Amith Yamasani742a6712011-05-04 14:49:28 -070013934
13935 private int applyUserId(int uid, int userId) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070013936 return UserHandle.getUid(userId, uid);
Amith Yamasani742a6712011-05-04 14:49:28 -070013937 }
13938
Dianne Hackborn599db5c2012-08-03 19:28:48 -070013939 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
Amith Yamasani2f6c9eb2012-02-06 15:31:35 -080013940 if (info == null) return null;
Amith Yamasani742a6712011-05-04 14:49:28 -070013941 ApplicationInfo newInfo = new ApplicationInfo(info);
13942 newInfo.uid = applyUserId(info.uid, userId);
Amith Yamasania4a54e22012-04-16 15:44:19 -070013943 newInfo.dataDir = USER_DATA_DIR + userId + "/"
13944 + info.packageName;
Amith Yamasani742a6712011-05-04 14:49:28 -070013945 return newInfo;
13946 }
13947
13948 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
Amith Yamasania4a54e22012-04-16 15:44:19 -070013949 if (aInfo == null
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070013950 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
Amith Yamasani742a6712011-05-04 14:49:28 -070013951 return aInfo;
13952 }
13953
13954 ActivityInfo info = new ActivityInfo(aInfo);
13955 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
13956 return info;
13957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013958}