blob: aa8ef2156278d6d2d454a504587ed6b826665107 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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 android.app;
18
Christopher Tate45281862010-03-05 15:46:30 -080019import android.app.backup.BackupAgent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070021import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.ComponentName;
23import android.content.ContentProvider;
24import android.content.Context;
25import android.content.IContentProvider;
26import android.content.Intent;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070027import android.content.IIntentReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.content.pm.ActivityInfo;
29import android.content.pm.ApplicationInfo;
30import android.content.pm.IPackageManager;
31import android.content.pm.InstrumentationInfo;
32import android.content.pm.PackageManager;
Sen Hubde75702010-05-28 01:54:03 -070033import android.content.pm.PackageManager.NameNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.pm.ProviderInfo;
35import android.content.pm.ServiceInfo;
36import android.content.res.AssetManager;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -070037import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.content.res.Configuration;
39import android.content.res.Resources;
40import android.database.sqlite.SQLiteDatabase;
41import android.database.sqlite.SQLiteDebug;
Vasu Noric3849202010-03-09 10:47:25 -080042import android.database.sqlite.SQLiteDebug.DbStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.graphics.Bitmap;
44import android.graphics.Canvas;
Jeff Brown98365d72012-08-19 20:30:52 -070045import android.hardware.display.DisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070046import android.hardware.display.DisplayManagerGlobal;
Robert Greenwalt434203a2010-10-11 16:00:27 -070047import android.net.IConnectivityManager;
48import android.net.Proxy;
49import android.net.ProxyProperties;
Romain Guya9582652011-11-10 14:20:10 -080050import android.opengl.GLUtils;
Joe Onoratod630f102011-03-17 18:42:26 -070051import android.os.AsyncTask;
Amith Yamasani742a6712011-05-04 14:49:28 -070052import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.os.Bundle;
54import android.os.Debug;
Geremy Condrab7faaf42012-09-19 18:07:42 -070055import android.os.DropBoxManager;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070056import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.os.Handler;
58import android.os.IBinder;
59import android.os.Looper;
60import android.os.Message;
61import android.os.MessageQueue;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070062import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.os.Process;
64import android.os.RemoteException;
65import android.os.ServiceManager;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -070066import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.os.SystemClock;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070068import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070069import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.util.AndroidRuntimeException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.util.DisplayMetrics;
72import android.util.EventLog;
73import android.util.Log;
Dianne Hackborn287952c2010-09-22 22:34:31 -070074import android.util.LogPrinter;
Jeff Brown6754ba22011-12-14 20:20:01 -080075import android.util.PrintWriterPrinter;
Dianne Hackbornc9421ba2010-03-11 22:23:46 -080076import android.util.Slog;
Jeff Brownd32460c2012-07-20 16:15:36 -070077import android.view.CompatibilityInfoHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.view.Display;
Romain Guy52339202010-09-03 16:04:46 -070079import android.view.HardwareRenderer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.view.View;
81import android.view.ViewDebug;
82import android.view.ViewManager;
Dianne Hackborn6dd005b2011-07-18 13:22:50 -070083import android.view.ViewRootImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import android.view.Window;
85import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -070086import android.view.WindowManagerGlobal;
Jason Samsa6f338c2012-02-24 16:22:16 -080087import android.renderscript.RenderScript;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088
89import com.android.internal.os.BinderInternal;
90import com.android.internal.os.RuntimeInit;
Bob Leee5408332009-09-04 18:31:17 -070091import com.android.internal.os.SamplingProfilerIntegration;
Jeff Sharkey6d515712012-09-20 16:06:08 -070092import com.android.internal.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093
94import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
95
96import java.io.File;
97import java.io.FileDescriptor;
98import java.io.FileOutputStream;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070099import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100import java.io.PrintWriter;
101import java.lang.ref.WeakReference;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700102import java.net.InetAddress;
Kenny Roote29df162012-08-10 08:28:37 -0700103import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104import java.util.ArrayList;
105import java.util.HashMap;
106import java.util.Iterator;
107import java.util.List;
108import java.util.Locale;
109import java.util.Map;
110import java.util.TimeZone;
111import java.util.regex.Pattern;
112
Geremy Condrab7faaf42012-09-19 18:07:42 -0700113import libcore.io.DropBox;
Geremy Condra69689a72012-09-11 16:57:17 -0700114import libcore.io.EventLogger;
Jeff Sharkeye861b422012-03-01 20:59:22 -0800115import libcore.io.IoUtils;
116
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -0800117import dalvik.system.CloseGuard;
Bob Leee5408332009-09-04 18:31:17 -0700118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119final class SuperNotCalledException extends AndroidRuntimeException {
120 public SuperNotCalledException(String msg) {
121 super(msg);
122 }
123}
124
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700125final class RemoteServiceException extends AndroidRuntimeException {
126 public RemoteServiceException(String msg) {
127 super(msg);
128 }
129}
130
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131/**
132 * This manages the execution of the main thread in an
133 * application process, scheduling and executing activities,
134 * broadcasts, and other operations on it as the activity
135 * manager requests.
136 *
137 * {@hide}
138 */
139public final class ActivityThread {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700140 /** @hide */
141 public static final String TAG = "ActivityThread";
Jim Miller0b2a6d02010-07-13 18:01:29 -0700142 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
Joe Onorato43a17652011-04-06 19:22:23 -0700143 static final boolean localLOGV = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700144 static final boolean DEBUG_MESSAGES = false;
Dianne Hackborne829fef2010-10-26 17:44:01 -0700145 /** @hide */
146 public static final boolean DEBUG_BROADCAST = false;
Chris Tate8a7dc172009-03-24 20:11:42 -0700147 private static final boolean DEBUG_RESULTS = false;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700148 private static final boolean DEBUG_BACKUP = false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700149 private static final boolean DEBUG_CONFIGURATION = false;
Dianne Hackborna0c283e2012-02-09 10:47:01 -0800150 private static final boolean DEBUG_SERVICE = false;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700151 private static final boolean DEBUG_MEMORY_TRIM = false;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700152 private static final boolean DEBUG_PROVIDER = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800153 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
154 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
155 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
156 private static final int LOG_ON_PAUSE_CALLED = 30021;
157 private static final int LOG_ON_RESUME_CALLED = 30022;
158
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700159 static ContextImpl mSystemContext = null;
Bob Leee5408332009-09-04 18:31:17 -0700160
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700161 static IPackageManager sPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800162
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700163 final ApplicationThread mAppThread = new ApplicationThread();
164 final Looper mLooper = Looper.myLooper();
165 final H mH = new H();
166 final HashMap<IBinder, ActivityClientRecord> mActivities
167 = new HashMap<IBinder, ActivityClientRecord>();
168 // List of new activities (via ActivityRecord.nextIdle) that should
169 // be reported when next we idle.
170 ActivityClientRecord mNewActivities = null;
171 // Number of activities that are currently visible on-screen.
172 int mNumVisibleActivities = 0;
173 final HashMap<IBinder, Service> mServices
174 = new HashMap<IBinder, Service>();
175 AppBindData mBoundApplication;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700176 Profiler mProfiler;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700177 int mCurDefaultDisplayDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700178 boolean mDensityCompatMode;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700179 Configuration mConfiguration;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700180 Configuration mCompatConfiguration;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700181 Configuration mResConfiguration;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700182 CompatibilityInfo mResCompatibilityInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700183 Application mInitialApplication;
184 final ArrayList<Application> mAllApplications
185 = new ArrayList<Application>();
186 // set of instantiated backup agents, keyed by package name
187 final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
Romain Guy65b345f2011-07-27 18:51:50 -0700188 static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700189 Instrumentation mInstrumentation;
190 String mInstrumentationAppDir = null;
Brian Carlstromd893a892012-04-01 21:30:26 -0700191 String mInstrumentationAppLibraryDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700192 String mInstrumentationAppPackage = null;
193 String mInstrumentedAppDir = null;
Brian Carlstromd893a892012-04-01 21:30:26 -0700194 String mInstrumentedAppLibraryDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700195 boolean mSystemThread = false;
196 boolean mJitEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700198 // These can be accessed by multiple threads; mPackages is the lock.
199 // XXX For now we keep around information about all packages we have
200 // seen, not removing entries from this map.
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800201 // NOTE: The activity and window managers need to call in to
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700202 // ActivityThread to do things like update resource configurations,
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800203 // which means this lock gets held while the activity and window managers
204 // holds their own lock. Thus you MUST NEVER call back into the activity manager
205 // or window manager or anything that depends on them while holding this lock.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700206 final HashMap<String, WeakReference<LoadedApk>> mPackages
207 = new HashMap<String, WeakReference<LoadedApk>>();
208 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
209 = new HashMap<String, WeakReference<LoadedApk>>();
Jeff Browna492c3a2012-08-23 19:48:44 -0700210 final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700211 = new HashMap<CompatibilityInfo, DisplayMetrics>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700212 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
213 = new HashMap<ResourcesKey, WeakReference<Resources> >();
214 final ArrayList<ActivityClientRecord> mRelaunchingActivities
215 = new ArrayList<ActivityClientRecord>();
216 Configuration mPendingConfiguration = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800217
Jeff Sharkey6d515712012-09-20 16:06:08 -0700218 private static final class ProviderKey {
219 final String authority;
220 final int userId;
221
222 public ProviderKey(String authority, int userId) {
223 this.authority = authority;
224 this.userId = userId;
225 }
226
227 @Override
228 public boolean equals(Object o) {
229 if (o instanceof ProviderKey) {
230 final ProviderKey other = (ProviderKey) o;
231 return Objects.equal(authority, other.authority) && userId == other.userId;
232 }
233 return false;
234 }
235
236 @Override
237 public int hashCode() {
238 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
239 }
240 }
241
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700242 // The lock of mProviderMap protects the following variables.
Jeff Sharkey6d515712012-09-20 16:06:08 -0700243 final HashMap<ProviderKey, ProviderClientRecord> mProviderMap
244 = new HashMap<ProviderKey, ProviderClientRecord>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700245 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
246 = new HashMap<IBinder, ProviderRefCount>();
247 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
248 = new HashMap<IBinder, ProviderClientRecord>();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700249 final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
250 = new HashMap<ComponentName, ProviderClientRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800251
Jeff Hamilton52d32032011-01-08 15:31:26 -0600252 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
253 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
254
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700255 final GcIdler mGcIdler = new GcIdler();
256 boolean mGcIdlerScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700258 static Handler sMainThreadHandler; // set once in main()
259
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800260 Bundle mCoreSettings = null;
261
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400262 static final class ActivityClientRecord {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 IBinder token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700264 int ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 Intent intent;
266 Bundle state;
267 Activity activity;
268 Window window;
269 Activity parent;
270 String embeddedID;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -0700271 Activity.NonConfigurationInstances lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 boolean paused;
273 boolean stopped;
274 boolean hideForNow;
275 Configuration newConfig;
Dianne Hackborne88846e2009-09-30 21:34:25 -0700276 Configuration createdConfig;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700277 ActivityClientRecord nextIdle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700279 String profileFile;
280 ParcelFileDescriptor profileFd;
281 boolean autoStopProfiler;
282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 ActivityInfo activityInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400284 CompatibilityInfo compatInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700285 LoadedApk packageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286
287 List<ResultInfo> pendingResults;
288 List<Intent> pendingIntents;
289
290 boolean startsNotResumed;
291 boolean isForward;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800292 int pendingConfigChanges;
293 boolean onlyLocalRequest;
294
295 View mPendingRemoveWindow;
296 WindowManager mPendingRemoveWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800297
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700298 ActivityClientRecord() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299 parent = null;
300 embeddedID = null;
301 paused = false;
302 stopped = false;
303 hideForNow = false;
304 nextIdle = null;
305 }
306
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800307 public boolean isPreHoneycomb() {
308 if (activity != null) {
309 return activity.getApplicationInfo().targetSdkVersion
310 < android.os.Build.VERSION_CODES.HONEYCOMB;
311 }
312 return false;
313 }
314
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 public String toString() {
Dianne Hackbornb61a0262012-05-14 17:19:18 -0700316 ComponentName componentName = intent != null ? intent.getComponent() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 return "ActivityRecord{"
318 + Integer.toHexString(System.identityHashCode(this))
319 + " token=" + token + " " + (componentName == null
320 ? "no component name" : componentName.toShortString())
321 + "}";
322 }
323 }
324
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700325 final class ProviderClientRecord {
326 final String[] mNames;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327 final IContentProvider mProvider;
328 final ContentProvider mLocalProvider;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700329 final IActivityManager.ContentProviderHolder mHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700331 ProviderClientRecord(String[] names, IContentProvider provider,
332 ContentProvider localProvider,
333 IActivityManager.ContentProviderHolder holder) {
334 mNames = names;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335 mProvider = provider;
336 mLocalProvider = localProvider;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700337 mHolder = holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800338 }
339 }
340
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400341 static final class NewIntentData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342 List<Intent> intents;
343 IBinder token;
344 public String toString() {
345 return "NewIntentData{intents=" + intents + " token=" + token + "}";
346 }
347 }
348
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400349 static final class ReceiverData extends BroadcastReceiver.PendingResult {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700350 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700351 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
352 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
353 token, sendingUser);
Dianne Hackborne829fef2010-10-26 17:44:01 -0700354 this.intent = intent;
355 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 Intent intent;
358 ActivityInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400359 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800360 public String toString() {
361 return "ReceiverData{intent=" + intent + " packageName=" +
Dianne Hackborne829fef2010-10-26 17:44:01 -0700362 info.packageName + " resultCode=" + getResultCode()
363 + " resultData=" + getResultData() + " resultExtras="
364 + getResultExtras(false) + "}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 }
366 }
367
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400368 static final class CreateBackupAgentData {
Christopher Tate181fafa2009-05-14 11:12:14 -0700369 ApplicationInfo appInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400370 CompatibilityInfo compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700371 int backupMode;
372 public String toString() {
373 return "CreateBackupAgentData{appInfo=" + appInfo
374 + " backupAgent=" + appInfo.backupAgentName
375 + " mode=" + backupMode + "}";
376 }
377 }
Bob Leee5408332009-09-04 18:31:17 -0700378
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400379 static final class CreateServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 IBinder token;
381 ServiceInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400382 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 Intent intent;
384 public String toString() {
385 return "CreateServiceData{token=" + token + " className="
386 + info.name + " packageName=" + info.packageName
387 + " intent=" + intent + "}";
388 }
389 }
390
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400391 static final class BindServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800392 IBinder token;
393 Intent intent;
394 boolean rebind;
395 public String toString() {
396 return "BindServiceData{token=" + token + " intent=" + intent + "}";
397 }
398 }
399
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400400 static final class ServiceArgsData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800401 IBinder token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700402 boolean taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 int startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700404 int flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 Intent args;
406 public String toString() {
407 return "ServiceArgsData{token=" + token + " startId=" + startId
408 + " args=" + args + "}";
409 }
410 }
411
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400412 static final class AppBindData {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700413 LoadedApk info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 String processName;
415 ApplicationInfo appInfo;
416 List<ProviderInfo> providers;
417 ComponentName instrumentationName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800418 Bundle instrumentationArgs;
419 IInstrumentationWatcher instrumentationWatcher;
420 int debugMode;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800421 boolean enableOpenGlTrace;
Christopher Tate181fafa2009-05-14 11:12:14 -0700422 boolean restrictedBackupMode;
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700423 boolean persistent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 Configuration config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400425 CompatibilityInfo compatInfo;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700426
427 /** Initial values for {@link Profiler}. */
428 String initProfileFile;
429 ParcelFileDescriptor initProfileFd;
430 boolean initAutoStopProfiler;
431
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 public String toString() {
433 return "AppBindData{appInfo=" + appInfo + "}";
434 }
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700435 }
436
437 static final class Profiler {
438 String profileFile;
439 ParcelFileDescriptor profileFd;
440 boolean autoStopProfiler;
441 boolean profiling;
442 boolean handlingProfiling;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700443 public void setProfiler(String file, ParcelFileDescriptor fd) {
444 if (profiling) {
445 if (fd != null) {
446 try {
447 fd.close();
448 } catch (IOException e) {
Romain Guya998dff2012-03-23 18:58:36 -0700449 // Ignore
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700450 }
451 }
452 return;
453 }
454 if (profileFd != null) {
455 try {
456 profileFd.close();
457 } catch (IOException e) {
Romain Guya998dff2012-03-23 18:58:36 -0700458 // Ignore
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700459 }
460 }
461 profileFile = file;
462 profileFd = fd;
463 }
464 public void startProfiling() {
465 if (profileFd == null || profiling) {
466 return;
467 }
468 try {
469 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
470 8 * 1024 * 1024, 0);
471 profiling = true;
472 } catch (RuntimeException e) {
473 Slog.w(TAG, "Profiling failed on path " + profileFile);
474 try {
475 profileFd.close();
476 profileFd = null;
477 } catch (IOException e2) {
478 Slog.w(TAG, "Failure closing profile fd", e2);
479 }
480 }
481 }
482 public void stopProfiling() {
483 if (profiling) {
484 profiling = false;
485 Debug.stopMethodTracing();
486 if (profileFd != null) {
487 try {
488 profileFd.close();
489 } catch (IOException e) {
490 }
491 }
492 profileFd = null;
493 profileFile = null;
494 }
495 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800496 }
497
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400498 static final class DumpComponentInfo {
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700499 ParcelFileDescriptor fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700500 IBinder token;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800501 String prefix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 String[] args;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800503 }
504
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400505 static final class ResultData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800506 IBinder token;
507 List<ResultInfo> results;
508 public String toString() {
509 return "ResultData{token=" + token + " results" + results + "}";
510 }
511 }
512
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400513 static final class ContextCleanupInfo {
Dianne Hackborn21556372010-02-04 16:34:40 -0800514 ContextImpl context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 String what;
516 String who;
517 }
518
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400519 static final class ProfilerControlData {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700520 String path;
521 ParcelFileDescriptor fd;
522 }
523
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400524 static final class DumpHeapData {
Andy McFadden824c5102010-07-09 16:26:57 -0700525 String path;
526 ParcelFileDescriptor fd;
527 }
528
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400529 static final class UpdateCompatibilityData {
530 String pkg;
531 CompatibilityInfo info;
532 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -0700533
Romain Guy65b345f2011-07-27 18:51:50 -0700534 private native void dumpGraphicsInfo(FileDescriptor fd);
Chet Haase9c1e23b2011-03-24 10:51:31 -0700535
Romain Guy65b345f2011-07-27 18:51:50 -0700536 private class ApplicationThread extends ApplicationThreadNative {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700537 private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
538 private static final String ONE_COUNT_COLUMN = "%21s %8d";
539 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
Vasu Nori3c7131f2010-09-21 14:36:57 -0700540 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
Bob Leee5408332009-09-04 18:31:17 -0700541
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542 // Formatting for checkin service - update version if row format changes
543 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
Bob Leee5408332009-09-04 18:31:17 -0700544
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700545 private void updatePendingConfiguration(Configuration config) {
546 synchronized (mPackages) {
547 if (mPendingConfiguration == null ||
548 mPendingConfiguration.isOtherSeqNewer(config)) {
549 mPendingConfiguration = config;
550 }
551 }
552 }
553
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800554 public final void schedulePauseActivity(IBinder token, boolean finished,
555 boolean userLeaving, int configChanges) {
556 queueOrSendMessage(
557 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
558 token,
559 (userLeaving ? 1 : 0),
560 configChanges);
561 }
562
563 public final void scheduleStopActivity(IBinder token, boolean showWindow,
564 int configChanges) {
565 queueOrSendMessage(
566 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
567 token, 0, configChanges);
568 }
569
570 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
571 queueOrSendMessage(
572 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
573 token);
574 }
575
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800576 public final void scheduleSleeping(IBinder token, boolean sleeping) {
577 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
578 }
579
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800580 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
581 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
582 }
583
584 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
585 ResultData res = new ResultData();
586 res.token = token;
587 res.results = results;
588 queueOrSendMessage(H.SEND_RESULT, res);
589 }
590
591 // we use token to identify this activity without having to send the
592 // activity itself back to the activity manager. (matters more with ipc)
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700593 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700594 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
595 Bundle state, List<ResultInfo> pendingResults,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700596 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
597 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700598 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800599
600 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700601 r.ident = ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800602 r.intent = intent;
603 r.activityInfo = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400604 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800605 r.state = state;
606
607 r.pendingResults = pendingResults;
608 r.pendingIntents = pendingNewIntents;
609
610 r.startsNotResumed = notResumed;
611 r.isForward = isForward;
612
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700613 r.profileFile = profileName;
614 r.profileFd = profileFd;
615 r.autoStopProfiler = autoStopProfiler;
616
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700617 updatePendingConfiguration(curConfig);
618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
620 }
621
622 public final void scheduleRelaunchActivity(IBinder token,
623 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
Dianne Hackborn871ecdc2009-12-11 15:24:33 -0800624 int configChanges, boolean notResumed, Configuration config) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800625 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
626 configChanges, notResumed, config, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 }
628
629 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
630 NewIntentData data = new NewIntentData();
631 data.intents = intents;
632 data.token = token;
633
634 queueOrSendMessage(H.NEW_INTENT, data);
635 }
636
637 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
638 int configChanges) {
639 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
640 configChanges);
641 }
642
643 public final void scheduleReceiver(Intent intent, ActivityInfo info,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400644 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700645 boolean sync, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700646 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700647 sync, false, mAppThread.asBinder(), sendingUser);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 r.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400649 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 queueOrSendMessage(H.RECEIVER, r);
651 }
652
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400653 public final void scheduleCreateBackupAgent(ApplicationInfo app,
654 CompatibilityInfo compatInfo, int backupMode) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700655 CreateBackupAgentData d = new CreateBackupAgentData();
656 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400657 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700658 d.backupMode = backupMode;
659
660 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
661 }
662
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400663 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
664 CompatibilityInfo compatInfo) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700665 CreateBackupAgentData d = new CreateBackupAgentData();
666 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400667 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700668
669 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
670 }
671
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800672 public final void scheduleCreateService(IBinder token,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400673 ServiceInfo info, CompatibilityInfo compatInfo) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 CreateServiceData s = new CreateServiceData();
675 s.token = token;
676 s.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400677 s.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800678
679 queueOrSendMessage(H.CREATE_SERVICE, s);
680 }
681
682 public final void scheduleBindService(IBinder token, Intent intent,
683 boolean rebind) {
684 BindServiceData s = new BindServiceData();
685 s.token = token;
686 s.intent = intent;
687 s.rebind = rebind;
688
Amith Yamasani742a6712011-05-04 14:49:28 -0700689 if (DEBUG_SERVICE)
690 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
691 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800692 queueOrSendMessage(H.BIND_SERVICE, s);
693 }
694
695 public final void scheduleUnbindService(IBinder token, Intent intent) {
696 BindServiceData s = new BindServiceData();
697 s.token = token;
698 s.intent = intent;
699
700 queueOrSendMessage(H.UNBIND_SERVICE, s);
701 }
702
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700703 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700704 int flags ,Intent args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800705 ServiceArgsData s = new ServiceArgsData();
706 s.token = token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700707 s.taskRemoved = taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800708 s.startId = startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700709 s.flags = flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 s.args = args;
711
712 queueOrSendMessage(H.SERVICE_ARGS, s);
713 }
714
715 public final void scheduleStopService(IBinder token) {
716 queueOrSendMessage(H.STOP_SERVICE, token);
717 }
718
719 public final void bindApplication(String processName,
720 ApplicationInfo appInfo, List<ProviderInfo> providers,
721 ComponentName instrumentationName, String profileFile,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700722 ParcelFileDescriptor profileFd, boolean autoStopProfiler,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800723 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
Siva Velusamy92a8b222012-03-09 16:24:04 -0800724 int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,
725 boolean persistent, Configuration config, CompatibilityInfo compatInfo,
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700726 Map<String, IBinder> services, Bundle coreSettings) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727
728 if (services != null) {
729 // Setup the service cache in the ServiceManager
730 ServiceManager.initServiceCache(services);
731 }
732
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800733 setCoreSettings(coreSettings);
734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800735 AppBindData data = new AppBindData();
736 data.processName = processName;
737 data.appInfo = appInfo;
738 data.providers = providers;
739 data.instrumentationName = instrumentationName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800740 data.instrumentationArgs = instrumentationArgs;
741 data.instrumentationWatcher = instrumentationWatcher;
742 data.debugMode = debugMode;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800743 data.enableOpenGlTrace = enableOpenGlTrace;
Christopher Tate181fafa2009-05-14 11:12:14 -0700744 data.restrictedBackupMode = isRestrictedBackupMode;
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700745 data.persistent = persistent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800746 data.config = config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400747 data.compatInfo = compatInfo;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700748 data.initProfileFile = profileFile;
749 data.initProfileFd = profileFd;
750 data.initAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800751 queueOrSendMessage(H.BIND_APPLICATION, data);
752 }
753
754 public final void scheduleExit() {
755 queueOrSendMessage(H.EXIT_APPLICATION, null);
756 }
757
Christopher Tate5e1ab332009-09-01 20:32:49 -0700758 public final void scheduleSuicide() {
759 queueOrSendMessage(H.SUICIDE, null);
760 }
761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 public void requestThumbnail(IBinder token) {
763 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
764 }
765
766 public void scheduleConfigurationChanged(Configuration config) {
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700767 updatePendingConfiguration(config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
769 }
770
771 public void updateTimeZone() {
772 TimeZone.setDefault(null);
773 }
774
Robert Greenwalt03595d02010-11-02 14:08:23 -0700775 public void clearDnsCache() {
776 // a non-standard API to get this to libcore
777 InetAddress.clearDnsCache();
778 }
779
Robert Greenwalt434203a2010-10-11 16:00:27 -0700780 public void setHttpProxy(String host, String port, String exclList) {
781 Proxy.setHttpProxySystemProperty(host, port, exclList);
782 }
783
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800784 public void processInBackground() {
785 mH.removeMessages(H.GC_WHEN_IDLE);
786 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
787 }
788
789 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700790 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700791 try {
792 data.fd = ParcelFileDescriptor.dup(fd);
793 data.token = servicetoken;
794 data.args = args;
795 queueOrSendMessage(H.DUMP_SERVICE, data);
796 } catch (IOException e) {
797 Slog.w(TAG, "dumpService failed", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800798 }
799 }
800
801 // This function exists to make sure all receiver dispatching is
802 // correctly ordered, since these are one-way calls and the binder driver
803 // applies transaction ordering per object for such calls.
804 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
Dianne Hackborn68d881c2009-10-05 13:58:17 -0700805 int resultCode, String dataStr, Bundle extras, boolean ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700806 boolean sticky, int sendingUser) throws RemoteException {
807 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
808 sticky, sendingUser);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 }
Bob Leee5408332009-09-04 18:31:17 -0700810
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 public void scheduleLowMemory() {
812 queueOrSendMessage(H.LOW_MEMORY, null);
813 }
814
815 public void scheduleActivityConfigurationChanged(IBinder token) {
816 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
817 }
818
Romain Guy7eabe552011-07-21 14:56:34 -0700819 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
820 int profileType) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700821 ProfilerControlData pcd = new ProfilerControlData();
822 pcd.path = path;
823 pcd.fd = fd;
Romain Guy7eabe552011-07-21 14:56:34 -0700824 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800825 }
826
Andy McFadden824c5102010-07-09 16:26:57 -0700827 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
828 DumpHeapData dhd = new DumpHeapData();
829 dhd.path = path;
830 dhd.fd = fd;
831 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
832 }
833
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700834 public void setSchedulingGroup(int group) {
835 // Note: do this immediately, since going into the foreground
836 // should happen regardless of what pending work we have to do
837 // and the activity manager will wait for us to report back that
838 // we are done before sending us to the background.
839 try {
840 Process.setProcessGroup(Process.myPid(), group);
841 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800842 Slog.w(TAG, "Failed setting process group to " + group, e);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700843 }
844 }
Bob Leee5408332009-09-04 18:31:17 -0700845
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700846 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
847 Debug.getMemoryInfo(outInfo);
848 }
Bob Leee5408332009-09-04 18:31:17 -0700849
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700850 public void dispatchPackageBroadcast(int cmd, String[] packages) {
851 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
852 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700853
854 public void scheduleCrash(String msg) {
855 queueOrSendMessage(H.SCHEDULE_CRASH, msg);
856 }
Dianne Hackborn625ac272010-09-17 18:29:22 -0700857
Dianne Hackborn30d71892010-12-11 10:37:55 -0800858 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
859 String prefix, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700860 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700861 try {
862 data.fd = ParcelFileDescriptor.dup(fd);
863 data.token = activitytoken;
864 data.prefix = prefix;
865 data.args = args;
866 queueOrSendMessage(H.DUMP_ACTIVITY, data);
867 } catch (IOException e) {
868 Slog.w(TAG, "dumpActivity failed", e);
Dianne Hackborn625ac272010-09-17 18:29:22 -0700869 }
870 }
Chet Haase9c1e23b2011-03-24 10:51:31 -0700871
Marco Nelissen18cb2872011-11-15 11:19:53 -0800872 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
873 String[] args) {
874 DumpComponentInfo data = new DumpComponentInfo();
875 try {
876 data.fd = ParcelFileDescriptor.dup(fd);
877 data.token = providertoken;
878 data.args = args;
879 queueOrSendMessage(H.DUMP_PROVIDER, data);
880 } catch (IOException e) {
881 Slog.w(TAG, "dumpProvider failed", e);
882 }
883 }
884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 @Override
Dianne Hackbornb437e092011-08-05 17:50:29 -0700886 public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
887 boolean all, String[] args) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700888 FileOutputStream fout = new FileOutputStream(fd);
889 PrintWriter pw = new PrintWriter(fout);
890 try {
Romain Guya998dff2012-03-23 18:58:36 -0700891 return dumpMemInfo(pw, checkin, all);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700892 } finally {
Chet Haase9c1e23b2011-03-24 10:51:31 -0700893 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -0700894 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700895 }
896
Romain Guya998dff2012-03-23 18:58:36 -0700897 private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 long nativeMax = Debug.getNativeHeapSize() / 1024;
899 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
900 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
901
902 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
903 Debug.getMemoryInfo(memInfo);
904
Dianne Hackbornb437e092011-08-05 17:50:29 -0700905 if (!all) {
906 return memInfo;
907 }
908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 Runtime runtime = Runtime.getRuntime();
910
911 long dalvikMax = runtime.totalMemory() / 1024;
912 long dalvikFree = runtime.freeMemory() / 1024;
913 long dalvikAllocated = dalvikMax - dalvikFree;
914 long viewInstanceCount = ViewDebug.getViewInstanceCount();
Romain Guy65b345f2011-07-27 18:51:50 -0700915 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
Brian Carlstromc21550a2010-10-05 21:34:06 -0700916 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
917 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800918 int globalAssetCount = AssetManager.getGlobalAssetCount();
919 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
920 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
921 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
922 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
Brian Carlstromc9d5b312010-10-05 22:23:41 -0700923 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
Vasu Noric3849202010-03-09 10:47:25 -0800924 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
Bob Leee5408332009-09-04 18:31:17 -0700925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 // For checkin, we print one long comma-separated list of values
Dianne Hackbornb437e092011-08-05 17:50:29 -0700927 if (checkin) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 // NOTE: if you change anything significant below, also consider changing
929 // ACTIVITY_THREAD_CHECKIN_VERSION.
Bob Leee5408332009-09-04 18:31:17 -0700930 String processName = (mBoundApplication != null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800931 ? mBoundApplication.processName : "unknown";
Bob Leee5408332009-09-04 18:31:17 -0700932
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 // Header
934 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
935 pw.print(Process.myPid()); pw.print(',');
936 pw.print(processName); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 // Heap info - max
939 pw.print(nativeMax); pw.print(',');
940 pw.print(dalvikMax); pw.print(',');
941 pw.print("N/A,");
942 pw.print(nativeMax + dalvikMax); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700943
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800944 // Heap info - allocated
945 pw.print(nativeAllocated); pw.print(',');
946 pw.print(dalvikAllocated); pw.print(',');
947 pw.print("N/A,");
948 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800950 // Heap info - free
951 pw.print(nativeFree); pw.print(',');
952 pw.print(dalvikFree); pw.print(',');
953 pw.print("N/A,");
954 pw.print(nativeFree + dalvikFree); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 // Heap info - proportional set size
957 pw.print(memInfo.nativePss); pw.print(',');
958 pw.print(memInfo.dalvikPss); pw.print(',');
959 pw.print(memInfo.otherPss); pw.print(',');
960 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700961
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 // Heap info - shared
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700963 pw.print(memInfo.nativeSharedDirty); pw.print(',');
964 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
965 pw.print(memInfo.otherSharedDirty); pw.print(',');
966 pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
967 + memInfo.otherSharedDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700968
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 // Heap info - private
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700970 pw.print(memInfo.nativePrivateDirty); pw.print(',');
971 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
972 pw.print(memInfo.otherPrivateDirty); pw.print(',');
973 pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
974 + memInfo.otherPrivateDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 // Object counts
977 pw.print(viewInstanceCount); pw.print(',');
978 pw.print(viewRootInstanceCount); pw.print(',');
979 pw.print(appContextInstanceCount); pw.print(',');
980 pw.print(activityInstanceCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 pw.print(globalAssetCount); pw.print(',');
983 pw.print(globalAssetManagerCount); pw.print(',');
984 pw.print(binderLocalObjectCount); pw.print(',');
985 pw.print(binderProxyObjectCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700986
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 pw.print(binderDeathObjectCount); pw.print(',');
988 pw.print(openSslSocketCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700989
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800990 // SQL
Vasu Noric3849202010-03-09 10:47:25 -0800991 pw.print(stats.memoryUsed / 1024); pw.print(',');
Jeff Brown2a293b62012-01-19 14:02:22 -0800992 pw.print(stats.memoryUsed / 1024); pw.print(',');
993 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
Dianne Hackbornb437e092011-08-05 17:50:29 -0700994 pw.print(stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -0800995 for (int i = 0; i < stats.dbStats.size(); i++) {
996 DbStats dbStats = stats.dbStats.get(i);
Dianne Hackbornb437e092011-08-05 17:50:29 -0700997 pw.print(','); pw.print(dbStats.dbName);
998 pw.print(','); pw.print(dbStats.pageSize);
999 pw.print(','); pw.print(dbStats.dbSize);
1000 pw.print(','); pw.print(dbStats.lookaside);
1001 pw.print(','); pw.print(dbStats.cache);
1002 pw.print(','); pw.print(dbStats.cache);
Vasu Noric3849202010-03-09 10:47:25 -08001003 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07001004 pw.println();
Bob Leee5408332009-09-04 18:31:17 -07001005
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001006 return memInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007 }
Bob Leee5408332009-09-04 18:31:17 -07001008
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 // otherwise, show human-readable format
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001010 printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
1011 printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
1012 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
1013 "------");
1014 printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
1015 memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
1016 printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
1017 memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001019 int otherPss = memInfo.otherPss;
1020 int otherSharedDirty = memInfo.otherSharedDirty;
1021 int otherPrivateDirty = memInfo.otherPrivateDirty;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001023 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
Romain Guy65b345f2011-07-27 18:51:50 -07001024 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001025 memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
1026 memInfo.getOtherPrivateDirty(i), "", "", "");
1027 otherPss -= memInfo.getOtherPss(i);
1028 otherSharedDirty -= memInfo.getOtherSharedDirty(i);
1029 otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
1030 }
1031
1032 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
1033 otherPrivateDirty, "", "", "");
1034 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
1035 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
1036 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
1037 nativeFree+dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001038
1039 pw.println(" ");
1040 pw.println(" Objects");
Romain Guy65b345f2011-07-27 18:51:50 -07001041 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001042 viewRootInstanceCount);
1043
1044 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1045 "Activities:", activityInstanceCount);
1046
1047 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1048 "AssetManagers:", globalAssetManagerCount);
1049
1050 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1051 "Proxy Binders:", binderProxyObjectCount);
1052 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
1053
1054 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
Bob Leee5408332009-09-04 18:31:17 -07001055
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001056 // SQLite mem info
1057 pw.println(" ");
1058 pw.println(" SQL");
Jeff Brown2a293b62012-01-19 14:02:22 -08001059 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1060 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1061 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -08001062 pw.println(" ");
1063 int N = stats.dbStats.size();
1064 if (N > 0) {
1065 pw.println(" DATABASES");
Vasu Nori3c7131f2010-09-21 14:36:57 -07001066 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1067 "Dbname");
Vasu Noric3849202010-03-09 10:47:25 -08001068 for (int i = 0; i < N; i++) {
1069 DbStats dbStats = stats.dbStats.get(i);
Vasu Nori3c7131f2010-09-21 14:36:57 -07001070 printRow(pw, DB_INFO_FORMAT,
1071 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1072 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1073 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1074 dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -08001075 }
1076 }
Bob Leee5408332009-09-04 18:31:17 -07001077
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001078 // Asset details.
1079 String assetAlloc = AssetManager.getAssetAllocations();
1080 if (assetAlloc != null) {
1081 pw.println(" ");
1082 pw.println(" Asset Allocations");
1083 pw.print(assetAlloc);
1084 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001085
1086 return memInfo;
1087 }
1088
1089 @Override
1090 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1091 dumpGraphicsInfo(fd);
Jeff Brown98365d72012-08-19 20:30:52 -07001092 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001093 }
1094
Jeff Brown6754ba22011-12-14 20:20:01 -08001095 @Override
1096 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1097 PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
1098 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1099 SQLiteDebug.dump(printer, args);
1100 pw.flush();
1101 }
1102
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001103 @Override
1104 public void unstableProviderDied(IBinder provider) {
1105 queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1106 }
1107
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001108 private void printRow(PrintWriter pw, String format, Object...objs) {
1109 pw.println(String.format(format, objs));
1110 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001111
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08001112 public void setCoreSettings(Bundle coreSettings) {
1113 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001114 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001115
1116 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1117 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1118 ucd.pkg = pkg;
1119 ucd.info = info;
1120 queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1121 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001122
1123 public void scheduleTrimMemory(int level) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001124 queueOrSendMessage(H.TRIM_MEMORY, null, level);
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001125 }
Marco Nelissen18cb2872011-11-15 11:19:53 -08001126
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 }
1128
Romain Guy65b345f2011-07-27 18:51:50 -07001129 private class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001130 public static final int LAUNCH_ACTIVITY = 100;
1131 public static final int PAUSE_ACTIVITY = 101;
1132 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1133 public static final int STOP_ACTIVITY_SHOW = 103;
1134 public static final int STOP_ACTIVITY_HIDE = 104;
1135 public static final int SHOW_WINDOW = 105;
1136 public static final int HIDE_WINDOW = 106;
1137 public static final int RESUME_ACTIVITY = 107;
1138 public static final int SEND_RESULT = 108;
Brian Carlstromed7e0072011-03-24 13:27:57 -07001139 public static final int DESTROY_ACTIVITY = 109;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 public static final int BIND_APPLICATION = 110;
1141 public static final int EXIT_APPLICATION = 111;
1142 public static final int NEW_INTENT = 112;
1143 public static final int RECEIVER = 113;
1144 public static final int CREATE_SERVICE = 114;
1145 public static final int SERVICE_ARGS = 115;
1146 public static final int STOP_SERVICE = 116;
1147 public static final int REQUEST_THUMBNAIL = 117;
1148 public static final int CONFIGURATION_CHANGED = 118;
1149 public static final int CLEAN_UP_CONTEXT = 119;
1150 public static final int GC_WHEN_IDLE = 120;
1151 public static final int BIND_SERVICE = 121;
1152 public static final int UNBIND_SERVICE = 122;
1153 public static final int DUMP_SERVICE = 123;
1154 public static final int LOW_MEMORY = 124;
1155 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1156 public static final int RELAUNCH_ACTIVITY = 126;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001157 public static final int PROFILER_CONTROL = 127;
Christopher Tate181fafa2009-05-14 11:12:14 -07001158 public static final int CREATE_BACKUP_AGENT = 128;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001159 public static final int DESTROY_BACKUP_AGENT = 129;
1160 public static final int SUICIDE = 130;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001161 public static final int REMOVE_PROVIDER = 131;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001162 public static final int ENABLE_JIT = 132;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001163 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001164 public static final int SCHEDULE_CRASH = 134;
Andy McFadden824c5102010-07-09 16:26:57 -07001165 public static final int DUMP_HEAP = 135;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001166 public static final int DUMP_ACTIVITY = 136;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001167 public static final int SLEEPING = 137;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001168 public static final int SET_CORE_SETTINGS = 138;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001169 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001170 public static final int TRIM_MEMORY = 140;
Marco Nelissen18cb2872011-11-15 11:19:53 -08001171 public static final int DUMP_PROVIDER = 141;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001172 public static final int UNSTABLE_PROVIDER_DIED = 142;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 String codeToString(int code) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001174 if (DEBUG_MESSAGES) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 switch (code) {
1176 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1177 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1178 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1179 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1180 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1181 case SHOW_WINDOW: return "SHOW_WINDOW";
1182 case HIDE_WINDOW: return "HIDE_WINDOW";
1183 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1184 case SEND_RESULT: return "SEND_RESULT";
1185 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1186 case BIND_APPLICATION: return "BIND_APPLICATION";
1187 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1188 case NEW_INTENT: return "NEW_INTENT";
1189 case RECEIVER: return "RECEIVER";
1190 case CREATE_SERVICE: return "CREATE_SERVICE";
1191 case SERVICE_ARGS: return "SERVICE_ARGS";
1192 case STOP_SERVICE: return "STOP_SERVICE";
1193 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
1194 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1195 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1196 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1197 case BIND_SERVICE: return "BIND_SERVICE";
1198 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1199 case DUMP_SERVICE: return "DUMP_SERVICE";
1200 case LOW_MEMORY: return "LOW_MEMORY";
1201 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1202 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001203 case PROFILER_CONTROL: return "PROFILER_CONTROL";
Christopher Tate181fafa2009-05-14 11:12:14 -07001204 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1205 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
Christopher Tate5e1ab332009-09-01 20:32:49 -07001206 case SUICIDE: return "SUICIDE";
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001207 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001208 case ENABLE_JIT: return "ENABLE_JIT";
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001209 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001210 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
Andy McFadden824c5102010-07-09 16:26:57 -07001211 case DUMP_HEAP: return "DUMP_HEAP";
Dianne Hackborn625ac272010-09-17 18:29:22 -07001212 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001213 case SLEEPING: return "SLEEPING";
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001214 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001215 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001216 case TRIM_MEMORY: return "TRIM_MEMORY";
Marco Nelissen18cb2872011-11-15 11:19:53 -08001217 case DUMP_PROVIDER: return "DUMP_PROVIDER";
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001218 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001219 }
1220 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001221 return Integer.toString(code);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 }
1223 public void handleMessage(Message msg) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001224 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 switch (msg.what) {
1226 case LAUNCH_ACTIVITY: {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001227 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001228 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001229
1230 r.packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001231 r.activityInfo.applicationInfo, r.compatInfo);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001232 handleLaunchActivity(r, null);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001233 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 } break;
1235 case RELAUNCH_ACTIVITY: {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001236 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001237 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08001238 handleRelaunchActivity(r);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001239 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 } break;
1241 case PAUSE_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001242 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
Bob Leee5408332009-09-04 18:31:17 -07001244 maybeSnapshot();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001245 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001246 break;
1247 case PAUSE_ACTIVITY_FINISHING:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001248 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001250 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 break;
1252 case STOP_ACTIVITY_SHOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001253 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001254 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001255 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 break;
1257 case STOP_ACTIVITY_HIDE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001258 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001259 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001260 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 break;
1262 case SHOW_WINDOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001263 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 handleWindowVisibility((IBinder)msg.obj, true);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001265 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 break;
1267 case HIDE_WINDOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001268 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001269 handleWindowVisibility((IBinder)msg.obj, false);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001270 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 break;
1272 case RESUME_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001273 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 handleResumeActivity((IBinder)msg.obj, true,
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001275 msg.arg1 != 0, true);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001276 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 break;
1278 case SEND_RESULT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001279 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001280 handleSendResult((ResultData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001281 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 break;
1283 case DESTROY_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001284 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1286 msg.arg2, false);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001287 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 break;
1289 case BIND_APPLICATION:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001290 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001291 AppBindData data = (AppBindData)msg.obj;
1292 handleBindApplication(data);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001293 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 break;
1295 case EXIT_APPLICATION:
1296 if (mInitialApplication != null) {
1297 mInitialApplication.onTerminate();
1298 }
1299 Looper.myLooper().quit();
1300 break;
1301 case NEW_INTENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001302 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001303 handleNewIntent((NewIntentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001304 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 break;
1306 case RECEIVER:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001307 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 handleReceiver((ReceiverData)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001309 maybeSnapshot();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001310 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 break;
1312 case CREATE_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001313 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 handleCreateService((CreateServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001315 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 break;
1317 case BIND_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001318 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 handleBindService((BindServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001320 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 break;
1322 case UNBIND_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001323 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 handleUnbindService((BindServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001325 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 break;
1327 case SERVICE_ARGS:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001328 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 handleServiceArgs((ServiceArgsData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001330 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 break;
1332 case STOP_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001333 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 handleStopService((IBinder)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001335 maybeSnapshot();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001336 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 break;
1338 case REQUEST_THUMBNAIL:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001339 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 handleRequestThumbnail((IBinder)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001341 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 break;
1343 case CONFIGURATION_CHANGED:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001344 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001345 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001346 handleConfigurationChanged((Configuration)msg.obj, null);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001347 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 break;
1349 case CLEAN_UP_CONTEXT:
1350 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1351 cci.context.performFinalCleanup(cci.who, cci.what);
1352 break;
1353 case GC_WHEN_IDLE:
1354 scheduleGcIdler();
1355 break;
1356 case DUMP_SERVICE:
Dianne Hackborn625ac272010-09-17 18:29:22 -07001357 handleDumpService((DumpComponentInfo)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 break;
1359 case LOW_MEMORY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001360 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361 handleLowMemory();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001362 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 break;
1364 case ACTIVITY_CONFIGURATION_CHANGED:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001365 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 handleActivityConfigurationChanged((IBinder)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001367 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 break;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001369 case PROFILER_CONTROL:
Romain Guy7eabe552011-07-21 14:56:34 -07001370 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001371 break;
Christopher Tate181fafa2009-05-14 11:12:14 -07001372 case CREATE_BACKUP_AGENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001373 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -07001374 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001375 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate181fafa2009-05-14 11:12:14 -07001376 break;
1377 case DESTROY_BACKUP_AGENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001378 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -07001379 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001380 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate181fafa2009-05-14 11:12:14 -07001381 break;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001382 case SUICIDE:
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001383 Process.killProcess(Process.myPid());
1384 break;
1385 case REMOVE_PROVIDER:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001386 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001387 completeRemoveProvider((ProviderRefCount)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001388 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate5e1ab332009-09-01 20:32:49 -07001389 break;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001390 case ENABLE_JIT:
1391 ensureJitEnabled();
1392 break;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001393 case DISPATCH_PACKAGE_BROADCAST:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001394 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001395 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001396 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001397 break;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001398 case SCHEDULE_CRASH:
1399 throw new RemoteServiceException((String)msg.obj);
Andy McFadden824c5102010-07-09 16:26:57 -07001400 case DUMP_HEAP:
1401 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1402 break;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001403 case DUMP_ACTIVITY:
1404 handleDumpActivity((DumpComponentInfo)msg.obj);
1405 break;
Marco Nelissen18cb2872011-11-15 11:19:53 -08001406 case DUMP_PROVIDER:
1407 handleDumpProvider((DumpComponentInfo)msg.obj);
1408 break;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001409 case SLEEPING:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001410 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001411 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001412 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001413 break;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001414 case SET_CORE_SETTINGS:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001415 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001416 handleSetCoreSettings((Bundle) msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001417 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001418 break;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001419 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1420 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001421 break;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001422 case TRIM_MEMORY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001423 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001424 handleTrimMemory(msg.arg1);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001425 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001426 break;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001427 case UNSTABLE_PROVIDER_DIED:
1428 handleUnstableProviderDied((IBinder)msg.obj, false);
1429 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001431 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 }
Bob Leee5408332009-09-04 18:31:17 -07001433
Brian Carlstromed7e0072011-03-24 13:27:57 -07001434 private void maybeSnapshot() {
1435 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
Sen Hubde75702010-05-28 01:54:03 -07001436 // convert the *private* ActivityThread.PackageInfo to *public* known
1437 // android.content.pm.PackageInfo
1438 String packageName = mBoundApplication.info.mPackageName;
1439 android.content.pm.PackageInfo packageInfo = null;
1440 try {
1441 Context context = getSystemContext();
1442 if(context == null) {
1443 Log.e(TAG, "cannot get a valid context");
1444 return;
1445 }
1446 PackageManager pm = context.getPackageManager();
1447 if(pm == null) {
1448 Log.e(TAG, "cannot get a valid PackageManager");
1449 return;
1450 }
1451 packageInfo = pm.getPackageInfo(
1452 packageName, PackageManager.GET_ACTIVITIES);
1453 } catch (NameNotFoundException e) {
1454 Log.e(TAG, "cannot get package info for " + packageName, e);
1455 }
1456 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
Bob Leee5408332009-09-04 18:31:17 -07001457 }
1458 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001459 }
1460
Romain Guy65b345f2011-07-27 18:51:50 -07001461 private class Idler implements MessageQueue.IdleHandler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001462 public final boolean queueIdle() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001463 ActivityClientRecord a = mNewActivities;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001464 boolean stopProfiling = false;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001465 if (mBoundApplication != null && mProfiler.profileFd != null
1466 && mProfiler.autoStopProfiler) {
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001467 stopProfiling = true;
1468 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 if (a != null) {
1470 mNewActivities = null;
1471 IActivityManager am = ActivityManagerNative.getDefault();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001472 ActivityClientRecord prev;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001473 do {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001474 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 TAG, "Reporting idle of " + a +
1476 " finished=" +
Romain Guy65b345f2011-07-27 18:51:50 -07001477 (a.activity != null && a.activity.mFinished));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 if (a.activity != null && !a.activity.mFinished) {
1479 try {
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001480 am.activityIdle(a.token, a.createdConfig, stopProfiling);
Dianne Hackborne88846e2009-09-30 21:34:25 -07001481 a.createdConfig = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07001483 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 }
1485 }
1486 prev = a;
1487 a = a.nextIdle;
1488 prev.nextIdle = null;
1489 } while (a != null);
1490 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001491 if (stopProfiling) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001492 mProfiler.stopProfiling();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001493 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001494 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001495 return false;
1496 }
1497 }
1498
1499 final class GcIdler implements MessageQueue.IdleHandler {
1500 public final boolean queueIdle() {
1501 doGcIfNeeded();
1502 return false;
1503 }
1504 }
1505
Romain Guy65b345f2011-07-27 18:51:50 -07001506 private static class ResourcesKey {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001507 final private String mResDir;
Jeff Browna492c3a2012-08-23 19:48:44 -07001508 final private int mDisplayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001509 final private Configuration mOverrideConfiguration;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001510 final private float mScale;
1511 final private int mHash;
Bob Leee5408332009-09-04 18:31:17 -07001512
Jeff Browna492c3a2012-08-23 19:48:44 -07001513 ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001514 mResDir = resDir;
Jeff Browna492c3a2012-08-23 19:48:44 -07001515 mDisplayId = displayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001516 if (overrideConfiguration != null) {
1517 if (Configuration.EMPTY.equals(overrideConfiguration)) {
1518 overrideConfiguration = null;
1519 }
1520 }
1521 mOverrideConfiguration = overrideConfiguration;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001522 mScale = scale;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001523 int hash = 17;
1524 hash = 31 * hash + mResDir.hashCode();
Jeff Browna492c3a2012-08-23 19:48:44 -07001525 hash = 31 * hash + mDisplayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001526 hash = 31 * hash + (mOverrideConfiguration != null
1527 ? mOverrideConfiguration.hashCode() : 0);
1528 hash = 31 * hash + Float.floatToIntBits(mScale);
1529 mHash = hash;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001530 }
Bob Leee5408332009-09-04 18:31:17 -07001531
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001532 @Override
1533 public int hashCode() {
1534 return mHash;
1535 }
1536
1537 @Override
1538 public boolean equals(Object obj) {
1539 if (!(obj instanceof ResourcesKey)) {
1540 return false;
1541 }
1542 ResourcesKey peer = (ResourcesKey) obj;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001543 if (!mResDir.equals(peer.mResDir)) {
1544 return false;
1545 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001546 if (mDisplayId != peer.mDisplayId) {
1547 return false;
1548 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001549 if (mOverrideConfiguration != peer.mOverrideConfiguration) {
1550 if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
1551 return false;
1552 }
1553 if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
1554 return false;
1555 }
1556 }
1557 if (mScale != peer.mScale) {
1558 return false;
1559 }
1560 return true;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001561 }
1562 }
1563
Romain Guy65b345f2011-07-27 18:51:50 -07001564 public static ActivityThread currentActivityThread() {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07001565 return sThreadLocal.get();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001566 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567
Romain Guy65b345f2011-07-27 18:51:50 -07001568 public static String currentPackageName() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001569 ActivityThread am = currentActivityThread();
1570 return (am != null && am.mBoundApplication != null)
1571 ? am.mBoundApplication.processName : null;
1572 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573
Romain Guy65b345f2011-07-27 18:51:50 -07001574 public static Application currentApplication() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001575 ActivityThread am = currentActivityThread();
1576 return am != null ? am.mInitialApplication : null;
1577 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001578
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001579 public static IPackageManager getPackageManager() {
1580 if (sPackageManager != null) {
1581 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1582 return sPackageManager;
1583 }
1584 IBinder b = ServiceManager.getService("package");
1585 //Slog.v("PackageManager", "default service binder = " + b);
1586 sPackageManager = IPackageManager.Stub.asInterface(b);
1587 //Slog.v("PackageManager", "default service = " + sPackageManager);
1588 return sPackageManager;
1589 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001590
Jeff Browna492c3a2012-08-23 19:48:44 -07001591 private void flushDisplayMetricsLocked() {
1592 mDefaultDisplayMetrics.clear();
1593 }
1594
1595 DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
1596 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1597 DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
1598 if (dm != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001599 return dm;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001600 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001601 dm = new DisplayMetrics();
Jeff Brown848c2dc2012-08-19 20:18:08 -07001602
Jeff Brownbd6e1502012-08-28 03:27:37 -07001603 DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
Jeff Brown848c2dc2012-08-19 20:18:08 -07001604 if (displayManager == null) {
1605 // may be null early in system startup
Jeff Brown848c2dc2012-08-19 20:18:08 -07001606 dm.setToDefaults();
1607 return dm;
1608 }
1609
Jeff Browna492c3a2012-08-23 19:48:44 -07001610 if (isDefaultDisplay) {
1611 mDefaultDisplayMetrics.put(ci, dm);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001612 }
Jeff Brown848c2dc2012-08-19 20:18:08 -07001613
Jeff Brownd32460c2012-07-20 16:15:36 -07001614 CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
1615 cih.set(ci);
Jeff Browna492c3a2012-08-23 19:48:44 -07001616 Display d = displayManager.getCompatibleDisplay(displayId, cih);
Jeff Browna3909a92012-09-09 00:57:09 -07001617 if (d != null) {
1618 d.getMetrics(dm);
1619 } else {
1620 // Display no longer exists
1621 // FIXME: This would not be a problem if we kept the Display object around
1622 // instead of using the raw display id everywhere. The Display object caches
1623 // its information even after the display has been removed.
1624 dm.setToDefaults();
1625 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001626 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1627 // + metrics.heightPixels + " den=" + metrics.density
1628 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001629 return dm;
1630 }
1631
Romain Guy65b345f2011-07-27 18:51:50 -07001632 private Configuration mMainThreadConfig = new Configuration();
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001633 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1634 CompatibilityInfo compat) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001635 if (config == null) {
1636 return null;
1637 }
1638 if (compat != null && !compat.supportsScreen()) {
1639 mMainThreadConfig.setTo(config);
1640 config = mMainThreadConfig;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001641 compat.applyToConfiguration(displayDensity, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001642 }
1643 return config;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001644 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001645
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001646 /**
1647 * Creates the top level Resources for applications with the given compatibility info.
1648 *
1649 * @param resDir the resource directory.
1650 * @param compInfo the compability info. It will use the default compatibility info when it's
1651 * null.
1652 */
Jeff Browna492c3a2012-08-23 19:48:44 -07001653 Resources getTopLevelResources(String resDir,
1654 int displayId, Configuration overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001655 CompatibilityInfo compInfo) {
Jeff Browna492c3a2012-08-23 19:48:44 -07001656 ResourcesKey key = new ResourcesKey(resDir,
1657 displayId, overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001658 compInfo.applicationScale);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001659 Resources r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001660 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001661 // Resources is app scale dependent.
1662 if (false) {
1663 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1664 + compInfo.applicationScale);
1665 }
1666 WeakReference<Resources> wr = mActiveResources.get(key);
1667 r = wr != null ? wr.get() : null;
1668 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1669 if (r != null && r.getAssets().isUpToDate()) {
1670 if (false) {
1671 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1672 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1673 }
1674 return r;
1675 }
1676 }
1677
1678 //if (r != null) {
1679 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1680 // + r + " " + resDir);
1681 //}
1682
1683 AssetManager assets = new AssetManager();
1684 if (assets.addAssetPath(resDir) == 0) {
1685 return null;
1686 }
1687
1688 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
Jeff Browna492c3a2012-08-23 19:48:44 -07001689 DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
Dianne Hackborn756220b2012-08-14 16:45:30 -07001690 Configuration config;
Jeff Browna492c3a2012-08-23 19:48:44 -07001691 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1692 if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07001693 config = new Configuration(getConfiguration());
Jeff Browna492c3a2012-08-23 19:48:44 -07001694 if (!isDefaultDisplay) {
1695 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
1696 }
1697 if (key.mOverrideConfiguration != null) {
1698 config.updateFrom(key.mOverrideConfiguration);
1699 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001700 } else {
1701 config = getConfiguration();
1702 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001703 r = new Resources(assets, dm, config, compInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001704 if (false) {
1705 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1706 + r.getConfiguration() + " appScale="
1707 + r.getCompatibilityInfo().applicationScale);
1708 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001709
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001710 synchronized (mPackages) {
1711 WeakReference<Resources> wr = mActiveResources.get(key);
1712 Resources existing = wr != null ? wr.get() : null;
1713 if (existing != null && existing.getAssets().isUpToDate()) {
1714 // Someone else already created the resources while we were
1715 // unlocked; go ahead and use theirs.
1716 r.getAssets().close();
1717 return existing;
1718 }
1719
1720 // XXX need to remove entries when weak references go away
1721 mActiveResources.put(key, new WeakReference<Resources>(r));
1722 return r;
1723 }
1724 }
1725
1726 /**
1727 * Creates the top level resources for the given package.
1728 */
Jeff Browna492c3a2012-08-23 19:48:44 -07001729 Resources getTopLevelResources(String resDir,
1730 int displayId, Configuration overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001731 LoadedApk pkgInfo) {
Jeff Browna492c3a2012-08-23 19:48:44 -07001732 return getTopLevelResources(resDir, displayId, overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001733 pkgInfo.mCompatibilityInfo.get());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001734 }
1735
1736 final Handler getHandler() {
1737 return mH;
1738 }
1739
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001740 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1741 int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001742 synchronized (mPackages) {
1743 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001744 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1745 ref = mPackages.get(packageName);
1746 } else {
1747 ref = mResourcePackages.get(packageName);
1748 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001749 LoadedApk packageInfo = ref != null ? ref.get() : null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001750 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001751 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1752 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 if (packageInfo != null && (packageInfo.mResources == null
1754 || packageInfo.mResources.getAssets().isUpToDate())) {
1755 if (packageInfo.isSecurityViolation()
1756 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1757 throw new SecurityException(
1758 "Requesting code from " + packageName
1759 + " to be run in process "
1760 + mBoundApplication.processName
1761 + "/" + mBoundApplication.appInfo.uid);
1762 }
1763 return packageInfo;
1764 }
1765 }
1766
1767 ApplicationInfo ai = null;
1768 try {
1769 ai = getPackageManager().getApplicationInfo(packageName,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001770 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 } catch (RemoteException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07001772 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001773 }
1774
1775 if (ai != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001776 return getPackageInfo(ai, compatInfo, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 }
1778
1779 return null;
1780 }
1781
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001782 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1783 int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1785 boolean securityViolation = includeCode && ai.uid != 0
1786 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001787 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
Amith Yamasani742a6712011-05-04 14:49:28 -07001788 : true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1790 |Context.CONTEXT_IGNORE_SECURITY))
1791 == Context.CONTEXT_INCLUDE_CODE) {
1792 if (securityViolation) {
1793 String msg = "Requesting code from " + ai.packageName
1794 + " (with uid " + ai.uid + ")";
1795 if (mBoundApplication != null) {
1796 msg = msg + " to be run in process "
1797 + mBoundApplication.processName + " (with uid "
1798 + mBoundApplication.appInfo.uid + ")";
1799 }
1800 throw new SecurityException(msg);
1801 }
1802 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001803 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001804 }
1805
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001806 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1807 CompatibilityInfo compatInfo) {
1808 return getPackageInfo(ai, compatInfo, null, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 }
1810
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001811 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1812 synchronized (mPackages) {
1813 WeakReference<LoadedApk> ref;
1814 if (includeCode) {
1815 ref = mPackages.get(packageName);
1816 } else {
1817 ref = mResourcePackages.get(packageName);
1818 }
1819 return ref != null ? ref.get() : null;
1820 }
1821 }
1822
Romain Guy65b345f2011-07-27 18:51:50 -07001823 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001824 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1825 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001826 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001827 if (includeCode) {
1828 ref = mPackages.get(aInfo.packageName);
1829 } else {
1830 ref = mResourcePackages.get(aInfo.packageName);
1831 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001832 LoadedApk packageInfo = ref != null ? ref.get() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001833 if (packageInfo == null || (packageInfo.mResources != null
1834 && !packageInfo.mResources.getAssets().isUpToDate())) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001835 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001836 : "Loading resource-only package ") + aInfo.packageName
1837 + " (in " + (mBoundApplication != null
1838 ? mBoundApplication.processName : null)
1839 + ")");
1840 packageInfo =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001841 new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001842 securityViolation, includeCode &&
1843 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1844 if (includeCode) {
1845 mPackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001846 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 } else {
1848 mResourcePackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001849 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001850 }
1851 }
1852 return packageInfo;
1853 }
1854 }
1855
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 ActivityThread() {
1857 }
1858
1859 public ApplicationThread getApplicationThread()
1860 {
1861 return mAppThread;
1862 }
1863
1864 public Instrumentation getInstrumentation()
1865 {
1866 return mInstrumentation;
1867 }
1868
1869 public Configuration getConfiguration() {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001870 return mResConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 }
1872
1873 public boolean isProfiling() {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001874 return mProfiler != null && mProfiler.profileFile != null
1875 && mProfiler.profileFd == null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 }
1877
1878 public String getProfileFilePath() {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001879 return mProfiler.profileFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001880 }
1881
1882 public Looper getLooper() {
1883 return mLooper;
1884 }
1885
1886 public Application getApplication() {
1887 return mInitialApplication;
1888 }
Bob Leee5408332009-09-04 18:31:17 -07001889
Dianne Hackbornd97c7ad2009-06-19 11:37:35 -07001890 public String getProcessName() {
1891 return mBoundApplication.processName;
1892 }
Bob Leee5408332009-09-04 18:31:17 -07001893
Dianne Hackborn21556372010-02-04 16:34:40 -08001894 public ContextImpl getSystemContext() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001895 synchronized (this) {
1896 if (mSystemContext == null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001897 ContextImpl context =
1898 ContextImpl.createSystemContext(this);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001899 LoadedApk info = new LoadedApk(this, "android", context, null,
1900 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001901 context.init(info, null, this);
1902 context.getResources().updateConfiguration(
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001903 getConfiguration(), getDisplayMetricsLocked(
Jeff Browna492c3a2012-08-23 19:48:44 -07001904 Display.DEFAULT_DISPLAY,
1905 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001906 mSystemContext = context;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001907 //Slog.i(TAG, "Created system resources " + context.getResources()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 // + ": " + context.getResources().getConfiguration());
1909 }
1910 }
1911 return mSystemContext;
1912 }
1913
Mike Cleron432b7132009-09-24 15:28:29 -07001914 public void installSystemApplicationInfo(ApplicationInfo info) {
1915 synchronized (this) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001916 ContextImpl context = getSystemContext();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001917 context.init(new LoadedApk(this, "android", context, info,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001918 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001919
1920 // give ourselves a default profiler
1921 mProfiler = new Profiler();
Mike Cleron432b7132009-09-24 15:28:29 -07001922 }
1923 }
1924
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001925 void ensureJitEnabled() {
1926 if (!mJitEnabled) {
1927 mJitEnabled = true;
1928 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1929 }
1930 }
1931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001932 void scheduleGcIdler() {
1933 if (!mGcIdlerScheduled) {
1934 mGcIdlerScheduled = true;
1935 Looper.myQueue().addIdleHandler(mGcIdler);
1936 }
1937 mH.removeMessages(H.GC_WHEN_IDLE);
1938 }
1939
1940 void unscheduleGcIdler() {
1941 if (mGcIdlerScheduled) {
1942 mGcIdlerScheduled = false;
1943 Looper.myQueue().removeIdleHandler(mGcIdler);
1944 }
1945 mH.removeMessages(H.GC_WHEN_IDLE);
1946 }
1947
1948 void doGcIfNeeded() {
1949 mGcIdlerScheduled = false;
1950 final long now = SystemClock.uptimeMillis();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001951 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001952 // + "m now=" + now);
1953 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001954 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 BinderInternal.forceGc("bg");
1956 }
1957 }
1958
Jeff Hamilton52d32032011-01-08 15:31:26 -06001959 public void registerOnActivityPausedListener(Activity activity,
1960 OnActivityPausedListener listener) {
1961 synchronized (mOnPauseListeners) {
1962 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1963 if (list == null) {
1964 list = new ArrayList<OnActivityPausedListener>();
1965 mOnPauseListeners.put(activity, list);
1966 }
1967 list.add(listener);
1968 }
1969 }
1970
Jeff Hamiltonce3224c2011-01-17 11:05:03 -08001971 public void unregisterOnActivityPausedListener(Activity activity,
1972 OnActivityPausedListener listener) {
1973 synchronized (mOnPauseListeners) {
1974 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1975 if (list != null) {
1976 list.remove(listener);
1977 }
1978 }
1979 }
1980
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 public final ActivityInfo resolveActivityInfo(Intent intent) {
1982 ActivityInfo aInfo = intent.resolveActivityInfo(
1983 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
1984 if (aInfo == null) {
1985 // Throw an exception.
1986 Instrumentation.checkStartActivityResult(
Dianne Hackborna4972e92012-03-14 10:38:05 -07001987 ActivityManager.START_CLASS_NOT_FOUND, intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988 }
1989 return aInfo;
1990 }
Bob Leee5408332009-09-04 18:31:17 -07001991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001992 public final Activity startActivityNow(Activity parent, String id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001993 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001994 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001995 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001996 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001997 r.ident = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001998 r.intent = intent;
1999 r.state = state;
2000 r.parent = parent;
2001 r.embeddedID = id;
2002 r.activityInfo = activityInfo;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002003 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 if (localLOGV) {
2005 ComponentName compname = intent.getComponent();
2006 String name;
2007 if (compname != null) {
2008 name = compname.toShortString();
2009 } else {
2010 name = "(Intent " + intent + ").getComponent() returned null";
2011 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002012 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002013 + ", comp=" + name
2014 + ", token=" + token);
2015 }
Christopher Tateb70f3df2009-04-07 16:07:59 -07002016 return performLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 }
2018
2019 public final Activity getActivity(IBinder token) {
2020 return mActivities.get(token).activity;
2021 }
2022
2023 public final void sendActivityResult(
2024 IBinder token, String id, int requestCode,
2025 int resultCode, Intent data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002026 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
Chris Tate8a7dc172009-03-24 20:11:42 -07002027 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002028 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2029 list.add(new ResultInfo(id, requestCode, resultCode, data));
2030 mAppThread.scheduleSendResult(token, list);
2031 }
2032
2033 // if the thread hasn't started yet, we don't have the handler, so just
2034 // save the messages until we're ready.
Romain Guy65b345f2011-07-27 18:51:50 -07002035 private void queueOrSendMessage(int what, Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036 queueOrSendMessage(what, obj, 0, 0);
2037 }
2038
Romain Guy65b345f2011-07-27 18:51:50 -07002039 private void queueOrSendMessage(int what, Object obj, int arg1) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002040 queueOrSendMessage(what, obj, arg1, 0);
2041 }
2042
Romain Guy65b345f2011-07-27 18:51:50 -07002043 private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002044 synchronized (this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002045 if (DEBUG_MESSAGES) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002046 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2047 + ": " + arg1 + " / " + obj);
2048 Message msg = Message.obtain();
2049 msg.what = what;
2050 msg.obj = obj;
2051 msg.arg1 = arg1;
2052 msg.arg2 = arg2;
2053 mH.sendMessage(msg);
2054 }
2055 }
2056
Dianne Hackborn21556372010-02-04 16:34:40 -08002057 final void scheduleContextCleanup(ContextImpl context, String who,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002058 String what) {
2059 ContextCleanupInfo cci = new ContextCleanupInfo();
2060 cci.context = context;
2061 cci.who = who;
2062 cci.what = what;
2063 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
2064 }
2065
Romain Guy65b345f2011-07-27 18:51:50 -07002066 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002067 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2068
2069 ActivityInfo aInfo = r.activityInfo;
2070 if (r.packageInfo == null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002071 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 Context.CONTEXT_INCLUDE_CODE);
2073 }
Bob Leee5408332009-09-04 18:31:17 -07002074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075 ComponentName component = r.intent.getComponent();
2076 if (component == null) {
2077 component = r.intent.resolveActivity(
2078 mInitialApplication.getPackageManager());
2079 r.intent.setComponent(component);
2080 }
2081
2082 if (r.activityInfo.targetActivity != null) {
2083 component = new ComponentName(r.activityInfo.packageName,
2084 r.activityInfo.targetActivity);
2085 }
2086
2087 Activity activity = null;
2088 try {
2089 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2090 activity = mInstrumentation.newActivity(
2091 cl, component.getClassName(), r.intent);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002092 StrictMode.incrementExpectedActivityCount(activity.getClass());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 r.intent.setExtrasClassLoader(cl);
2094 if (r.state != null) {
2095 r.state.setClassLoader(cl);
2096 }
2097 } catch (Exception e) {
2098 if (!mInstrumentation.onException(activity, e)) {
2099 throw new RuntimeException(
2100 "Unable to instantiate activity " + component
2101 + ": " + e.toString(), e);
2102 }
2103 }
2104
2105 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002106 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07002107
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002108 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2109 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002110 TAG, r + ": app=" + app
2111 + ", appName=" + app.getPackageName()
2112 + ", pkg=" + r.packageInfo.getPackageName()
2113 + ", comp=" + r.intent.getComponent().toShortString()
2114 + ", dir=" + r.packageInfo.getAppDir());
2115
2116 if (activity != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08002117 ContextImpl appContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 appContext.init(r.packageInfo, r.token, this);
2119 appContext.setOuterContext(activity);
2120 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002121 Configuration config = new Configuration(mCompatConfiguration);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002122 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002123 + r.activityInfo.name + " with config " + config);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002124 activity.attach(appContext, this, getInstrumentation(), r.token,
2125 r.ident, app, r.intent, r.activityInfo, title, r.parent,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002126 r.embeddedID, r.lastNonConfigurationInstances, config);
Bob Leee5408332009-09-04 18:31:17 -07002127
Christopher Tateb70f3df2009-04-07 16:07:59 -07002128 if (customIntent != null) {
2129 activity.mIntent = customIntent;
2130 }
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002131 r.lastNonConfigurationInstances = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002132 activity.mStartedActivity = false;
2133 int theme = r.activityInfo.getThemeResource();
2134 if (theme != 0) {
2135 activity.setTheme(theme);
2136 }
2137
2138 activity.mCalled = false;
2139 mInstrumentation.callActivityOnCreate(activity, r.state);
2140 if (!activity.mCalled) {
2141 throw new SuperNotCalledException(
2142 "Activity " + r.intent.getComponent().toShortString() +
2143 " did not call through to super.onCreate()");
2144 }
2145 r.activity = activity;
2146 r.stopped = true;
2147 if (!r.activity.mFinished) {
2148 activity.performStart();
2149 r.stopped = false;
2150 }
2151 if (!r.activity.mFinished) {
2152 if (r.state != null) {
2153 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2154 }
2155 }
2156 if (!r.activity.mFinished) {
2157 activity.mCalled = false;
2158 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2159 if (!activity.mCalled) {
2160 throw new SuperNotCalledException(
2161 "Activity " + r.intent.getComponent().toShortString() +
2162 " did not call through to super.onPostCreate()");
2163 }
2164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165 }
2166 r.paused = true;
2167
2168 mActivities.put(r.token, r);
2169
2170 } catch (SuperNotCalledException e) {
2171 throw e;
2172
2173 } catch (Exception e) {
2174 if (!mInstrumentation.onException(activity, e)) {
2175 throw new RuntimeException(
2176 "Unable to start activity " + component
2177 + ": " + e.toString(), e);
2178 }
2179 }
2180
2181 return activity;
2182 }
2183
Romain Guy65b345f2011-07-27 18:51:50 -07002184 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 // If we are getting ready to gc after going to the background, well
2186 // we are back active so skip it.
2187 unscheduleGcIdler();
2188
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002189 if (r.profileFd != null) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07002190 mProfiler.setProfiler(r.profileFile, r.profileFd);
2191 mProfiler.startProfiling();
2192 mProfiler.autoStopProfiler = r.autoStopProfiler;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002193 }
2194
Dianne Hackborn58f42a52011-10-10 13:46:34 -07002195 // Make sure we are running with the most recent config.
2196 handleConfigurationChanged(null, null);
2197
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002198 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002199 TAG, "Handling launch of " + r);
Christopher Tateb70f3df2009-04-07 16:07:59 -07002200 Activity a = performLaunchActivity(r, customIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002201
2202 if (a != null) {
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08002203 r.createdConfig = new Configuration(mConfiguration);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002204 Bundle oldState = r.state;
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002205 handleResumeActivity(r.token, false, r.isForward,
2206 !r.activity.mFinished && !r.startsNotResumed);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002207
2208 if (!r.activity.mFinished && r.startsNotResumed) {
2209 // The activity manager actually wants this one to start out
2210 // paused, because it needs to be visible but isn't in the
2211 // foreground. We accomplish this by going through the
2212 // normal startup (because activities expect to go through
2213 // onResume() the first time they run, before their window
2214 // is displayed), and then pausing it. However, in this case
2215 // we do -not- need to do the full pause cycle (of freezing
2216 // and such) because the activity manager assumes it can just
2217 // retain the current state it has.
2218 try {
2219 r.activity.mCalled = false;
2220 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002221 // We need to keep around the original state, in case
Dianne Hackborn03fcc332012-05-15 12:49:40 -07002222 // we need to be created again. But we only do this
2223 // for pre-Honeycomb apps, which always save their state
2224 // when pausing, so we can not have them save their state
2225 // when restarting from a paused state. For HC and later,
2226 // we want to (and can) let the state be saved as the normal
2227 // part of stopping the activity.
2228 if (r.isPreHoneycomb()) {
2229 r.state = oldState;
2230 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231 if (!r.activity.mCalled) {
2232 throw new SuperNotCalledException(
2233 "Activity " + r.intent.getComponent().toShortString() +
2234 " did not call through to super.onPause()");
2235 }
2236
2237 } catch (SuperNotCalledException e) {
2238 throw e;
2239
2240 } catch (Exception e) {
2241 if (!mInstrumentation.onException(r.activity, e)) {
2242 throw new RuntimeException(
2243 "Unable to pause activity "
2244 + r.intent.getComponent().toShortString()
2245 + ": " + e.toString(), e);
2246 }
2247 }
2248 r.paused = true;
2249 }
2250 } else {
2251 // If there was an error, for any reason, tell the activity
2252 // manager to stop us.
2253 try {
2254 ActivityManagerNative.getDefault()
2255 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
2256 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07002257 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 }
2259 }
2260 }
2261
Romain Guy65b345f2011-07-27 18:51:50 -07002262 private void deliverNewIntents(ActivityClientRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002263 List<Intent> intents) {
2264 final int N = intents.size();
2265 for (int i=0; i<N; i++) {
2266 Intent intent = intents.get(i);
2267 intent.setExtrasClassLoader(r.activity.getClassLoader());
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002268 r.activity.mFragments.noteStateNotSaved();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2270 }
2271 }
2272
2273 public final void performNewIntents(IBinder token,
2274 List<Intent> intents) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002275 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 if (r != null) {
2277 final boolean resumed = !r.paused;
2278 if (resumed) {
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002279 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002280 mInstrumentation.callActivityOnPause(r.activity);
2281 }
2282 deliverNewIntents(r, intents);
2283 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07002284 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002285 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 }
2287 }
2288 }
Bob Leee5408332009-09-04 18:31:17 -07002289
Romain Guy65b345f2011-07-27 18:51:50 -07002290 private void handleNewIntent(NewIntentData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 performNewIntents(data.token, data.intents);
2292 }
2293
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002294 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2295
2296 /**
2297 * Return the Intent that's currently being handled by a
2298 * BroadcastReceiver on this thread, or null if none.
2299 * @hide
2300 */
2301 public static Intent getIntentBeingBroadcast() {
2302 return sCurrentBroadcastIntent.get();
2303 }
2304
Romain Guy65b345f2011-07-27 18:51:50 -07002305 private void handleReceiver(ReceiverData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 // If we are getting ready to gc after going to the background, well
2307 // we are back active so skip it.
2308 unscheduleGcIdler();
2309
2310 String component = data.intent.getComponent().getClassName();
2311
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002312 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002313 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002314
2315 IActivityManager mgr = ActivityManagerNative.getDefault();
2316
Romain Guy65b345f2011-07-27 18:51:50 -07002317 BroadcastReceiver receiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002318 try {
2319 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2320 data.intent.setExtrasClassLoader(cl);
Dianne Hackborne829fef2010-10-26 17:44:01 -07002321 data.setExtrasClassLoader(cl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002322 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2323 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07002324 if (DEBUG_BROADCAST) Slog.i(TAG,
2325 "Finishing failed broadcast to " + data.intent.getComponent());
2326 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002327 throw new RuntimeException(
2328 "Unable to instantiate receiver " + component
2329 + ": " + e.toString(), e);
2330 }
2331
2332 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002333 Application app = packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07002334
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002335 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 TAG, "Performing receive of " + data.intent
2337 + ": app=" + app
2338 + ", appName=" + app.getPackageName()
2339 + ", pkg=" + packageInfo.getPackageName()
2340 + ", comp=" + data.intent.getComponent().toShortString()
2341 + ", dir=" + packageInfo.getAppDir());
2342
Dianne Hackborn21556372010-02-04 16:34:40 -08002343 ContextImpl context = (ContextImpl)app.getBaseContext();
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002344 sCurrentBroadcastIntent.set(data.intent);
Dianne Hackborne829fef2010-10-26 17:44:01 -07002345 receiver.setPendingResult(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002346 receiver.onReceive(context.getReceiverRestrictedContext(),
2347 data.intent);
2348 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07002349 if (DEBUG_BROADCAST) Slog.i(TAG,
2350 "Finishing failed broadcast to " + data.intent.getComponent());
2351 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 if (!mInstrumentation.onException(receiver, e)) {
2353 throw new RuntimeException(
2354 "Unable to start receiver " + component
2355 + ": " + e.toString(), e);
2356 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002357 } finally {
2358 sCurrentBroadcastIntent.set(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 }
2360
Dianne Hackborne829fef2010-10-26 17:44:01 -07002361 if (receiver.getPendingResult() != null) {
2362 data.finish();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 }
2364 }
2365
Christopher Tate181fafa2009-05-14 11:12:14 -07002366 // Instantiate a BackupAgent and tell it that it's alive
Romain Guy65b345f2011-07-27 18:51:50 -07002367 private void handleCreateBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002368 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002369
2370 // no longer idle; we have backup work to do
2371 unscheduleGcIdler();
2372
2373 // instantiate the BackupAgent class named in the manifest
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002374 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002375 String packageName = packageInfo.mPackageName;
2376 if (mBackupAgents.get(packageName) != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002377 Slog.d(TAG, "BackupAgent " + " for " + packageName
Christopher Tate181fafa2009-05-14 11:12:14 -07002378 + " already exists");
2379 return;
2380 }
Bob Leee5408332009-09-04 18:31:17 -07002381
Christopher Tate181fafa2009-05-14 11:12:14 -07002382 BackupAgent agent = null;
2383 String classname = data.appInfo.backupAgentName;
Christopher Tate4a627c72011-04-01 14:43:32 -07002384
Christopher Tate79ec80d2011-06-24 14:58:49 -07002385 // full backup operation but no app-supplied agent? use the default implementation
2386 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2387 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
Christopher Tate4a627c72011-04-01 14:43:32 -07002388 classname = "android.app.backup.FullBackupAgent";
Christopher Tate181fafa2009-05-14 11:12:14 -07002389 }
Christopher Tate4a627c72011-04-01 14:43:32 -07002390
Christopher Tate181fafa2009-05-14 11:12:14 -07002391 try {
Christopher Tated1475e02009-07-09 15:36:17 -07002392 IBinder binder = null;
2393 try {
Christopher Tate4a627c72011-04-01 14:43:32 -07002394 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2395
Christopher Tated1475e02009-07-09 15:36:17 -07002396 java.lang.ClassLoader cl = packageInfo.getClassLoader();
Christopher Tate4a627c72011-04-01 14:43:32 -07002397 agent = (BackupAgent) cl.loadClass(classname).newInstance();
Christopher Tated1475e02009-07-09 15:36:17 -07002398
2399 // set up the agent's context
Dianne Hackborn21556372010-02-04 16:34:40 -08002400 ContextImpl context = new ContextImpl();
Christopher Tated1475e02009-07-09 15:36:17 -07002401 context.init(packageInfo, null, this);
2402 context.setOuterContext(agent);
2403 agent.attach(context);
2404
2405 agent.onCreate();
2406 binder = agent.onBind();
2407 mBackupAgents.put(packageName, agent);
2408 } catch (Exception e) {
2409 // If this is during restore, fail silently; otherwise go
2410 // ahead and let the user see the crash.
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002411 Slog.e(TAG, "Agent threw during creation: " + e);
Christopher Tate75a99702011-05-18 16:28:19 -07002412 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2413 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
Christopher Tated1475e02009-07-09 15:36:17 -07002414 throw e;
2415 }
2416 // falling through with 'binder' still null
2417 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002418
2419 // tell the OS that we're live now
Christopher Tate181fafa2009-05-14 11:12:14 -07002420 try {
2421 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2422 } catch (RemoteException e) {
2423 // nothing to do.
2424 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002425 } catch (Exception e) {
2426 throw new RuntimeException("Unable to create BackupAgent "
Christopher Tate4a627c72011-04-01 14:43:32 -07002427 + classname + ": " + e.toString(), e);
Christopher Tate181fafa2009-05-14 11:12:14 -07002428 }
2429 }
2430
2431 // Tear down a BackupAgent
Romain Guy65b345f2011-07-27 18:51:50 -07002432 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002433 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
Bob Leee5408332009-09-04 18:31:17 -07002434
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002435 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002436 String packageName = packageInfo.mPackageName;
2437 BackupAgent agent = mBackupAgents.get(packageName);
2438 if (agent != null) {
2439 try {
2440 agent.onDestroy();
2441 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002442 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002443 e.printStackTrace();
2444 }
2445 mBackupAgents.remove(packageName);
2446 } else {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002447 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002448 }
2449 }
2450
Romain Guy65b345f2011-07-27 18:51:50 -07002451 private void handleCreateService(CreateServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 // If we are getting ready to gc after going to the background, well
2453 // we are back active so skip it.
2454 unscheduleGcIdler();
2455
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002456 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002457 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002458 Service service = null;
2459 try {
2460 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2461 service = (Service) cl.loadClass(data.info.name).newInstance();
2462 } catch (Exception e) {
2463 if (!mInstrumentation.onException(service, e)) {
2464 throw new RuntimeException(
2465 "Unable to instantiate service " + data.info.name
2466 + ": " + e.toString(), e);
2467 }
2468 }
2469
2470 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002471 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002472
Dianne Hackborn21556372010-02-04 16:34:40 -08002473 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002474 context.init(packageInfo, null, this);
2475
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002476 Application app = packageInfo.makeApplication(false, mInstrumentation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002477 context.setOuterContext(service);
2478 service.attach(context, this, data.info.name, data.token, app,
2479 ActivityManagerNative.getDefault());
2480 service.onCreate();
2481 mServices.put(data.token, service);
2482 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002483 ActivityManagerNative.getDefault().serviceDoneExecuting(
2484 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 } catch (RemoteException e) {
2486 // nothing to do.
2487 }
2488 } catch (Exception e) {
2489 if (!mInstrumentation.onException(service, e)) {
2490 throw new RuntimeException(
2491 "Unable to create service " + data.info.name
2492 + ": " + e.toString(), e);
2493 }
2494 }
2495 }
2496
Romain Guy65b345f2011-07-27 18:51:50 -07002497 private void handleBindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 Service s = mServices.get(data.token);
Amith Yamasani742a6712011-05-04 14:49:28 -07002499 if (DEBUG_SERVICE)
2500 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002501 if (s != null) {
2502 try {
2503 data.intent.setExtrasClassLoader(s.getClassLoader());
2504 try {
2505 if (!data.rebind) {
2506 IBinder binder = s.onBind(data.intent);
2507 ActivityManagerNative.getDefault().publishService(
2508 data.token, data.intent, binder);
2509 } else {
2510 s.onRebind(data.intent);
2511 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002512 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002514 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002515 } catch (RemoteException ex) {
2516 }
2517 } catch (Exception e) {
2518 if (!mInstrumentation.onException(s, e)) {
2519 throw new RuntimeException(
2520 "Unable to bind to service " + s
2521 + " with " + data.intent + ": " + e.toString(), e);
2522 }
2523 }
2524 }
2525 }
2526
Romain Guy65b345f2011-07-27 18:51:50 -07002527 private void handleUnbindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002528 Service s = mServices.get(data.token);
2529 if (s != null) {
2530 try {
2531 data.intent.setExtrasClassLoader(s.getClassLoader());
2532 boolean doRebind = s.onUnbind(data.intent);
2533 try {
2534 if (doRebind) {
2535 ActivityManagerNative.getDefault().unbindFinished(
2536 data.token, data.intent, doRebind);
2537 } else {
2538 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002539 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002540 }
2541 } catch (RemoteException ex) {
2542 }
2543 } catch (Exception e) {
2544 if (!mInstrumentation.onException(s, e)) {
2545 throw new RuntimeException(
2546 "Unable to unbind to service " + s
2547 + " with " + data.intent + ": " + e.toString(), e);
2548 }
2549 }
2550 }
2551 }
2552
Dianne Hackborn625ac272010-09-17 18:29:22 -07002553 private void handleDumpService(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002554 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2555 try {
2556 Service s = mServices.get(info.token);
2557 if (s != null) {
2558 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2559 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2560 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002561 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002562 } finally {
2563 IoUtils.closeQuietly(info.fd);
2564 StrictMode.setThreadPolicy(oldPolicy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002565 }
2566 }
2567
Dianne Hackborn625ac272010-09-17 18:29:22 -07002568 private void handleDumpActivity(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002569 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2570 try {
2571 ActivityClientRecord r = mActivities.get(info.token);
2572 if (r != null && r.activity != null) {
2573 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2574 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2575 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07002576 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002577 } finally {
2578 IoUtils.closeQuietly(info.fd);
2579 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackborn625ac272010-09-17 18:29:22 -07002580 }
2581 }
2582
Marco Nelissen18cb2872011-11-15 11:19:53 -08002583 private void handleDumpProvider(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002584 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2585 try {
2586 ProviderClientRecord r = mLocalProviders.get(info.token);
2587 if (r != null && r.mLocalProvider != null) {
2588 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2589 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2590 pw.flush();
Marco Nelissen18cb2872011-11-15 11:19:53 -08002591 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002592 } finally {
2593 IoUtils.closeQuietly(info.fd);
2594 StrictMode.setThreadPolicy(oldPolicy);
Marco Nelissen18cb2872011-11-15 11:19:53 -08002595 }
2596 }
2597
Romain Guy65b345f2011-07-27 18:51:50 -07002598 private void handleServiceArgs(ServiceArgsData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002599 Service s = mServices.get(data.token);
2600 if (s != null) {
2601 try {
2602 if (data.args != null) {
2603 data.args.setExtrasClassLoader(s.getClassLoader());
2604 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002605 int res;
2606 if (!data.taskRemoved) {
2607 res = s.onStartCommand(data.args, data.flags, data.startId);
2608 } else {
2609 s.onTaskRemoved(data.args);
2610 res = Service.START_TASK_REMOVED_COMPLETE;
2611 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002612
2613 QueuedWork.waitToFinish();
2614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002615 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002616 ActivityManagerNative.getDefault().serviceDoneExecuting(
2617 data.token, 1, data.startId, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 } catch (RemoteException e) {
2619 // nothing to do.
2620 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002621 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002622 } catch (Exception e) {
2623 if (!mInstrumentation.onException(s, e)) {
2624 throw new RuntimeException(
2625 "Unable to start service " + s
2626 + " with " + data.args + ": " + e.toString(), e);
2627 }
2628 }
2629 }
2630 }
2631
Romain Guy65b345f2011-07-27 18:51:50 -07002632 private void handleStopService(IBinder token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 Service s = mServices.remove(token);
2634 if (s != null) {
2635 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002636 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637 s.onDestroy();
2638 Context context = s.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002639 if (context instanceof ContextImpl) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002640 final String who = s.getClassName();
Dianne Hackborn21556372010-02-04 16:34:40 -08002641 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002642 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002643
2644 QueuedWork.waitToFinish();
2645
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002646 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002647 ActivityManagerNative.getDefault().serviceDoneExecuting(
2648 token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 } catch (RemoteException e) {
2650 // nothing to do.
2651 }
2652 } catch (Exception e) {
2653 if (!mInstrumentation.onException(s, e)) {
2654 throw new RuntimeException(
2655 "Unable to stop service " + s
2656 + ": " + e.toString(), e);
2657 }
2658 }
2659 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002660 //Slog.i(TAG, "Running services: " + mServices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002661 }
2662
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002663 public final ActivityClientRecord performResumeActivity(IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 boolean clearHide) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002665 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002666 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 + " finished=" + r.activity.mFinished);
2668 if (r != null && !r.activity.mFinished) {
2669 if (clearHide) {
2670 r.hideForNow = false;
2671 r.activity.mStartedActivity = false;
2672 }
2673 try {
2674 if (r.pendingIntents != null) {
2675 deliverNewIntents(r, r.pendingIntents);
2676 r.pendingIntents = null;
2677 }
2678 if (r.pendingResults != null) {
2679 deliverResults(r, r.pendingResults);
2680 r.pendingResults = null;
2681 }
2682 r.activity.performResume();
2683
Bob Leee5408332009-09-04 18:31:17 -07002684 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 r.activity.getComponentName().getClassName());
Bob Leee5408332009-09-04 18:31:17 -07002686
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002687 r.paused = false;
2688 r.stopped = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689 r.state = null;
2690 } catch (Exception e) {
2691 if (!mInstrumentation.onException(r.activity, e)) {
2692 throw new RuntimeException(
2693 "Unable to resume activity "
2694 + r.intent.getComponent().toShortString()
2695 + ": " + e.toString(), e);
2696 }
2697 }
2698 }
2699 return r;
2700 }
2701
Romain Guya998dff2012-03-23 18:58:36 -07002702 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002703 if (r.mPendingRemoveWindow != null) {
2704 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2705 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2706 if (wtoken != null) {
Jeff Brown98365d72012-08-19 20:30:52 -07002707 WindowManagerGlobal.getInstance().closeAll(wtoken,
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002708 r.activity.getClass().getName(), "Activity");
2709 }
2710 }
2711 r.mPendingRemoveWindow = null;
2712 r.mPendingRemoveWindowManager = null;
2713 }
2714
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002715 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2716 boolean reallyResume) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002717 // If we are getting ready to gc after going to the background, well
2718 // we are back active so skip it.
2719 unscheduleGcIdler();
2720
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002721 ActivityClientRecord r = performResumeActivity(token, clearHide);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722
2723 if (r != null) {
2724 final Activity a = r.activity;
2725
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002726 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002727 TAG, "Resume " + r + " started activity: " +
2728 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2729 + ", finished: " + a.mFinished);
2730
2731 final int forwardBit = isForward ?
2732 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
Bob Leee5408332009-09-04 18:31:17 -07002733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 // If the window hasn't yet been added to the window manager,
2735 // and this guy didn't finish itself or start another activity,
2736 // then go ahead and add the window.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002737 boolean willBeVisible = !a.mStartedActivity;
2738 if (!willBeVisible) {
2739 try {
2740 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2741 a.getActivityToken());
2742 } catch (RemoteException e) {
2743 }
2744 }
2745 if (r.window == null && !a.mFinished && willBeVisible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 r.window = r.activity.getWindow();
2747 View decor = r.window.getDecorView();
2748 decor.setVisibility(View.INVISIBLE);
2749 ViewManager wm = a.getWindowManager();
2750 WindowManager.LayoutParams l = r.window.getAttributes();
2751 a.mDecor = decor;
2752 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2753 l.softInputMode |= forwardBit;
2754 if (a.mVisibleFromClient) {
2755 a.mWindowAdded = true;
2756 wm.addView(decor, l);
2757 }
2758
2759 // If the window has already been added, but during resume
2760 // we started another activity, then don't yet make the
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002761 // window visible.
2762 } else if (!willBeVisible) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002763 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 TAG, "Launch " + r + " mStartedActivity set");
2765 r.hideForNow = true;
2766 }
2767
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002768 // Get rid of anything left hanging around.
2769 cleanUpPendingRemoveWindows(r);
2770
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002771 // The window is now visible if it has been added, we are not
2772 // simply finishing, and we are not starting another activity.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002773 if (!r.activity.mFinished && willBeVisible
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002774 && r.activity.mDecor != null && !r.hideForNow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002775 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002776 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002777 + r.activityInfo.name + " with newConfig " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 performConfigurationChanged(r.activity, r.newConfig);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07002779 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002780 r.newConfig = null;
2781 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002782 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 + isForward);
2784 WindowManager.LayoutParams l = r.window.getAttributes();
2785 if ((l.softInputMode
2786 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2787 != forwardBit) {
2788 l.softInputMode = (l.softInputMode
2789 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2790 | forwardBit;
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002791 if (r.activity.mVisibleFromClient) {
2792 ViewManager wm = a.getWindowManager();
2793 View decor = r.window.getDecorView();
2794 wm.updateViewLayout(decor, l);
2795 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002796 }
2797 r.activity.mVisibleFromServer = true;
2798 mNumVisibleActivities++;
2799 if (r.activity.mVisibleFromClient) {
2800 r.activity.makeVisible();
2801 }
2802 }
2803
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002804 if (!r.onlyLocalRequest) {
2805 r.nextIdle = mNewActivities;
2806 mNewActivities = r;
2807 if (localLOGV) Slog.v(
2808 TAG, "Scheduling idle handler for " + r);
2809 Looper.myQueue().addIdleHandler(new Idler());
2810 }
2811 r.onlyLocalRequest = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002812
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002813 // Tell the activity manager we have resumed.
2814 if (reallyResume) {
2815 try {
2816 ActivityManagerNative.getDefault().activityResumed(token);
2817 } catch (RemoteException ex) {
2818 }
2819 }
2820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 } else {
2822 // If an exception was thrown when trying to resume, then
2823 // just end this activity.
2824 try {
2825 ActivityManagerNative.getDefault()
2826 .finishActivity(token, Activity.RESULT_CANCELED, null);
2827 } catch (RemoteException ex) {
2828 }
2829 }
2830 }
2831
2832 private int mThumbnailWidth = -1;
2833 private int mThumbnailHeight = -1;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002834 private Bitmap mAvailThumbnailBitmap = null;
2835 private Canvas mThumbnailCanvas = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002836
Romain Guy65b345f2011-07-27 18:51:50 -07002837 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002838 Bitmap thumbnail = mAvailThumbnailBitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002839 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002840 if (thumbnail == null) {
2841 int w = mThumbnailWidth;
2842 int h;
2843 if (w < 0) {
2844 Resources res = r.activity.getResources();
2845 mThumbnailHeight = h =
2846 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002847
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002848 mThumbnailWidth = w =
2849 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2850 } else {
2851 h = mThumbnailHeight;
2852 }
2853
2854 // On platforms where we don't want thumbnails, set dims to (0,0)
2855 if ((w > 0) && (h > 0)) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07002856 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
2857 w, h, THUMBNAIL_FORMAT);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002858 thumbnail.eraseColor(0);
2859 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 }
2861
Dianne Hackbornfb3806d2010-12-09 13:14:12 -08002862 if (thumbnail != null) {
2863 Canvas cv = mThumbnailCanvas;
2864 if (cv == null) {
2865 mThumbnailCanvas = cv = new Canvas();
2866 }
2867
2868 cv.setBitmap(thumbnail);
2869 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2870 mAvailThumbnailBitmap = thumbnail;
2871 thumbnail = null;
2872 }
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07002873 cv.setBitmap(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002874 }
Jim Miller0b2a6d02010-07-13 18:01:29 -07002875
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002876 } catch (Exception e) {
2877 if (!mInstrumentation.onException(r.activity, e)) {
2878 throw new RuntimeException(
2879 "Unable to create thumbnail of "
2880 + r.intent.getComponent().toShortString()
2881 + ": " + e.toString(), e);
2882 }
2883 thumbnail = null;
2884 }
2885
2886 return thumbnail;
2887 }
2888
Romain Guy65b345f2011-07-27 18:51:50 -07002889 private void handlePauseActivity(IBinder token, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002890 boolean userLeaving, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002891 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002892 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002893 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002894 if (userLeaving) {
2895 performUserLeavingActivity(r);
2896 }
Bob Leee5408332009-09-04 18:31:17 -07002897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002899 performPauseActivity(token, finished, r.isPreHoneycomb());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002900
Dianne Hackbornaa93bcd2010-10-27 13:57:00 -07002901 // Make sure any pending writes are now committed.
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002902 if (r.isPreHoneycomb()) {
2903 QueuedWork.waitToFinish();
2904 }
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 // Tell the activity manager we have paused.
2907 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002908 ActivityManagerNative.getDefault().activityPaused(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002909 } catch (RemoteException ex) {
2910 }
2911 }
2912 }
2913
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002914 final void performUserLeavingActivity(ActivityClientRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002915 mInstrumentation.callActivityOnUserLeaving(r.activity);
2916 }
2917
2918 final Bundle performPauseActivity(IBinder token, boolean finished,
2919 boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002920 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002921 return r != null ? performPauseActivity(r, finished, saveState) : null;
2922 }
2923
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002924 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002925 boolean saveState) {
2926 if (r.paused) {
2927 if (r.activity.mFinished) {
2928 // If we are finishing, we won't call onResume() in certain cases.
2929 // So here we likewise don't want to call onPause() if the activity
2930 // isn't resumed.
2931 return null;
2932 }
2933 RuntimeException e = new RuntimeException(
2934 "Performing pause of activity that is not resumed: "
2935 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002936 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 }
2938 Bundle state = null;
2939 if (finished) {
2940 r.activity.mFinished = true;
2941 }
2942 try {
2943 // Next have the activity save its current state and managed dialogs...
2944 if (!r.activity.mFinished && saveState) {
2945 state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04002946 state.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2948 r.state = state;
2949 }
2950 // Now we are idle.
2951 r.activity.mCalled = false;
2952 mInstrumentation.callActivityOnPause(r.activity);
2953 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
2954 if (!r.activity.mCalled) {
2955 throw new SuperNotCalledException(
2956 "Activity " + r.intent.getComponent().toShortString() +
2957 " did not call through to super.onPause()");
2958 }
2959
2960 } catch (SuperNotCalledException e) {
2961 throw e;
2962
2963 } catch (Exception e) {
2964 if (!mInstrumentation.onException(r.activity, e)) {
2965 throw new RuntimeException(
2966 "Unable to pause activity "
2967 + r.intent.getComponent().toShortString()
2968 + ": " + e.toString(), e);
2969 }
2970 }
2971 r.paused = true;
Jeff Hamilton52d32032011-01-08 15:31:26 -06002972
2973 // Notify any outstanding on paused listeners
2974 ArrayList<OnActivityPausedListener> listeners;
2975 synchronized (mOnPauseListeners) {
2976 listeners = mOnPauseListeners.remove(r.activity);
2977 }
2978 int size = (listeners != null ? listeners.size() : 0);
2979 for (int i = 0; i < size; i++) {
2980 listeners.get(i).onPaused(r.activity);
2981 }
2982
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002983 return state;
2984 }
2985
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002986 final void performStopActivity(IBinder token, boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002987 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002988 performStopActivityInner(r, null, false, saveState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 }
2990
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07002991 private static class StopInfo implements Runnable {
2992 ActivityClientRecord activity;
2993 Bundle state;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002994 Bitmap thumbnail;
2995 CharSequence description;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07002996
2997 @Override public void run() {
2998 // Tell activity manager we have been stopped.
2999 try {
3000 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3001 ActivityManagerNative.getDefault().activityStopped(
3002 activity.token, state, thumbnail, description);
3003 } catch (RemoteException ex) {
3004 }
3005 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 }
3007
Jeff Brownddaa9ac2011-11-11 20:16:14 -08003008 private static final class ProviderRefCount {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003009 public final IActivityManager.ContentProviderHolder holder;
3010 public final ProviderClientRecord client;
3011 public int stableCount;
3012 public int unstableCount;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08003013
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003014 // When this is set, the stable and unstable ref counts are 0 and
3015 // we have a pending operation scheduled to remove the ref count
3016 // from the activity manager. On the activity manager we are still
3017 // holding an unstable ref, though it is not reflected in the counts
3018 // here.
3019 public boolean removePending;
3020
3021 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3022 ProviderClientRecord inClient, int sCount, int uCount) {
3023 holder = inHolder;
3024 client = inClient;
3025 stableCount = sCount;
3026 unstableCount = uCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003027 }
3028 }
3029
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003030 /**
3031 * Core implementation of stopping an activity. Note this is a little
3032 * tricky because the server's meaning of stop is slightly different
3033 * than our client -- for the server, stop means to save state and give
3034 * it the result when it is done, but the window may still be visible.
3035 * For the client, we want to call onStop()/onStart() to indicate when
3036 * the activity's UI visibillity changes.
3037 */
Romain Guy65b345f2011-07-27 18:51:50 -07003038 private void performStopActivityInner(ActivityClientRecord r,
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003039 StopInfo info, boolean keepShown, boolean saveState) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003040 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003041 Bundle state = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003042 if (r != null) {
3043 if (!keepShown && r.stopped) {
3044 if (r.activity.mFinished) {
3045 // If we are finishing, we won't call onResume() in certain
3046 // cases. So here we likewise don't want to call onStop()
3047 // if the activity isn't resumed.
3048 return;
3049 }
3050 RuntimeException e = new RuntimeException(
3051 "Performing stop of activity that is not resumed: "
3052 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003053 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003054 }
3055
3056 if (info != null) {
3057 try {
3058 // First create a thumbnail for the activity...
Dianne Hackborn0500b3c2011-11-01 15:28:43 -07003059 // For now, don't create the thumbnail here; we are
3060 // doing that by doing a screen snapshot.
3061 info.thumbnail = null; //createThumbnailBitmap(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003062 info.description = r.activity.onCreateDescription();
3063 } catch (Exception e) {
3064 if (!mInstrumentation.onException(r.activity, e)) {
3065 throw new RuntimeException(
3066 "Unable to save state of activity "
3067 + r.intent.getComponent().toShortString()
3068 + ": " + e.toString(), e);
3069 }
3070 }
3071 }
3072
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003073 // Next have the activity save its current state and managed dialogs...
3074 if (!r.activity.mFinished && saveState) {
3075 if (r.state == null) {
3076 state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04003077 state.setAllowFds(false);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003078 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3079 r.state = state;
3080 } else {
3081 state = r.state;
3082 }
3083 }
3084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003085 if (!keepShown) {
3086 try {
3087 // Now we are idle.
3088 r.activity.performStop();
3089 } catch (Exception e) {
3090 if (!mInstrumentation.onException(r.activity, e)) {
3091 throw new RuntimeException(
3092 "Unable to stop activity "
3093 + r.intent.getComponent().toShortString()
3094 + ": " + e.toString(), e);
3095 }
3096 }
3097 r.stopped = true;
3098 }
3099
3100 r.paused = true;
3101 }
3102 }
3103
Romain Guy65b345f2011-07-27 18:51:50 -07003104 private void updateVisibility(ActivityClientRecord r, boolean show) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003105 View v = r.activity.mDecor;
3106 if (v != null) {
3107 if (show) {
3108 if (!r.activity.mVisibleFromServer) {
3109 r.activity.mVisibleFromServer = true;
3110 mNumVisibleActivities++;
3111 if (r.activity.mVisibleFromClient) {
3112 r.activity.makeVisible();
3113 }
3114 }
3115 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003116 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003117 + r.activityInfo.name + " with new config " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003118 performConfigurationChanged(r.activity, r.newConfig);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003119 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003120 r.newConfig = null;
3121 }
3122 } else {
3123 if (r.activity.mVisibleFromServer) {
3124 r.activity.mVisibleFromServer = false;
3125 mNumVisibleActivities--;
3126 v.setVisibility(View.INVISIBLE);
3127 }
3128 }
3129 }
3130 }
3131
Romain Guy65b345f2011-07-27 18:51:50 -07003132 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003133 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003134 r.activity.mConfigChangeFlags |= configChanges;
3135
3136 StopInfo info = new StopInfo();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003137 performStopActivityInner(r, info, show, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003138
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003139 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003140 TAG, "Finishing stop of " + r + ": show=" + show
3141 + " win=" + r.window);
3142
3143 updateVisibility(r, show);
Bob Leee5408332009-09-04 18:31:17 -07003144
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08003145 // Make sure any pending writes are now committed.
3146 if (!r.isPreHoneycomb()) {
3147 QueuedWork.waitToFinish();
3148 }
3149
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07003150 // Schedule the call to tell the activity manager we have
3151 // stopped. We don't do this immediately, because we want to
3152 // have a chance for any other pending work (in particular memory
3153 // trim requests) to complete before you tell the activity
3154 // manager to proceed and allow us to go fully into the background.
3155 info.activity = r;
3156 info.state = r.state;
3157 mH.post(info);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003158 }
3159
3160 final void performRestartActivity(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003161 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003162 if (r.stopped) {
3163 r.activity.performRestart();
3164 r.stopped = false;
3165 }
3166 }
3167
Romain Guy65b345f2011-07-27 18:51:50 -07003168 private void handleWindowVisibility(IBinder token, boolean show) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003169 ActivityClientRecord r = mActivities.get(token);
Dianne Hackbornbfddc0f2010-12-14 11:28:01 -08003170
3171 if (r == null) {
3172 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3173 return;
3174 }
3175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 if (!show && !r.stopped) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003177 performStopActivityInner(r, null, show, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 } else if (show && r.stopped) {
3179 // If we are getting ready to gc after going to the background, well
3180 // we are back active so skip it.
3181 unscheduleGcIdler();
3182
3183 r.activity.performRestart();
3184 r.stopped = false;
3185 }
3186 if (r.activity.mDecor != null) {
Joe Onorato43a17652011-04-06 19:22:23 -07003187 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003188 TAG, "Handle window " + r + " visibility: " + show);
3189 updateVisibility(r, show);
3190 }
3191 }
3192
Romain Guy65b345f2011-07-27 18:51:50 -07003193 private void handleSleeping(IBinder token, boolean sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003194 ActivityClientRecord r = mActivities.get(token);
3195
3196 if (r == null) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08003197 Log.w(TAG, "handleSleeping: no activity for token " + token);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003198 return;
3199 }
3200
3201 if (sleeping) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08003202 if (!r.stopped && !r.isPreHoneycomb()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003203 try {
3204 // Now we are idle.
3205 r.activity.performStop();
3206 } catch (Exception e) {
3207 if (!mInstrumentation.onException(r.activity, e)) {
3208 throw new RuntimeException(
3209 "Unable to stop activity "
3210 + r.intent.getComponent().toShortString()
3211 + ": " + e.toString(), e);
3212 }
3213 }
3214 r.stopped = true;
3215 }
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08003216
3217 // Make sure any pending writes are now committed.
3218 if (!r.isPreHoneycomb()) {
3219 QueuedWork.waitToFinish();
3220 }
3221
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003222 // Tell activity manager we slept.
3223 try {
3224 ActivityManagerNative.getDefault().activitySlept(r.token);
3225 } catch (RemoteException ex) {
3226 }
3227 } else {
3228 if (r.stopped && r.activity.mVisibleFromServer) {
3229 r.activity.performRestart();
3230 r.stopped = false;
3231 }
3232 }
3233 }
3234
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003235 private void handleSetCoreSettings(Bundle coreSettings) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08003236 synchronized (mPackages) {
3237 mCoreSettings = coreSettings;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003238 }
3239 }
3240
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003241 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3242 LoadedApk apk = peekPackageInfo(data.pkg, false);
3243 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003244 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003245 }
3246 apk = peekPackageInfo(data.pkg, true);
3247 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003248 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003249 }
3250 handleConfigurationChanged(mConfiguration, data.info);
Jeff Brown98365d72012-08-19 20:30:52 -07003251 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003252 }
3253
Romain Guy65b345f2011-07-27 18:51:50 -07003254 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003255 final int N = results.size();
3256 for (int i=0; i<N; i++) {
3257 ResultInfo ri = results.get(i);
3258 try {
3259 if (ri.mData != null) {
3260 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3261 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003262 if (DEBUG_RESULTS) Slog.v(TAG,
Chris Tate8a7dc172009-03-24 20:11:42 -07003263 "Delivering result to activity " + r + " : " + ri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003264 r.activity.dispatchActivityResult(ri.mResultWho,
3265 ri.mRequestCode, ri.mResultCode, ri.mData);
3266 } catch (Exception e) {
3267 if (!mInstrumentation.onException(r.activity, e)) {
3268 throw new RuntimeException(
3269 "Failure delivering result " + ri + " to activity "
3270 + r.intent.getComponent().toShortString()
3271 + ": " + e.toString(), e);
3272 }
3273 }
3274 }
3275 }
3276
Romain Guy65b345f2011-07-27 18:51:50 -07003277 private void handleSendResult(ResultData res) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003278 ActivityClientRecord r = mActivities.get(res.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003279 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 if (r != null) {
3281 final boolean resumed = !r.paused;
3282 if (!r.activity.mFinished && r.activity.mDecor != null
3283 && r.hideForNow && resumed) {
3284 // We had hidden the activity because it started another
3285 // one... we have gotten a result back and we are not
3286 // paused, so make sure our window is visible.
3287 updateVisibility(r, true);
3288 }
3289 if (resumed) {
3290 try {
3291 // Now we are idle.
3292 r.activity.mCalled = false;
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07003293 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003294 mInstrumentation.callActivityOnPause(r.activity);
3295 if (!r.activity.mCalled) {
3296 throw new SuperNotCalledException(
3297 "Activity " + r.intent.getComponent().toShortString()
3298 + " did not call through to super.onPause()");
3299 }
3300 } catch (SuperNotCalledException e) {
3301 throw e;
3302 } catch (Exception e) {
3303 if (!mInstrumentation.onException(r.activity, e)) {
3304 throw new RuntimeException(
3305 "Unable to pause activity "
3306 + r.intent.getComponent().toShortString()
3307 + ": " + e.toString(), e);
3308 }
3309 }
3310 }
3311 deliverResults(r, res.results);
3312 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07003313 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07003314 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 }
3316 }
3317 }
3318
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003319 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 return performDestroyActivity(token, finishing, 0, false);
3321 }
3322
Romain Guy65b345f2011-07-27 18:51:50 -07003323 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003325 ActivityClientRecord r = mActivities.get(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003326 Class activityClass = null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003327 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003328 if (r != null) {
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003329 activityClass = r.activity.getClass();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003330 r.activity.mConfigChangeFlags |= configChanges;
3331 if (finishing) {
3332 r.activity.mFinished = true;
3333 }
3334 if (!r.paused) {
3335 try {
3336 r.activity.mCalled = false;
3337 mInstrumentation.callActivityOnPause(r.activity);
Bob Leee5408332009-09-04 18:31:17 -07003338 EventLog.writeEvent(LOG_ON_PAUSE_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 r.activity.getComponentName().getClassName());
3340 if (!r.activity.mCalled) {
3341 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003342 "Activity " + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003343 + " did not call through to super.onPause()");
3344 }
3345 } catch (SuperNotCalledException e) {
3346 throw e;
3347 } catch (Exception e) {
3348 if (!mInstrumentation.onException(r.activity, e)) {
3349 throw new RuntimeException(
3350 "Unable to pause activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003351 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003352 + ": " + e.toString(), e);
3353 }
3354 }
3355 r.paused = true;
3356 }
3357 if (!r.stopped) {
3358 try {
3359 r.activity.performStop();
3360 } catch (SuperNotCalledException e) {
3361 throw e;
3362 } catch (Exception e) {
3363 if (!mInstrumentation.onException(r.activity, e)) {
3364 throw new RuntimeException(
3365 "Unable to stop activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003366 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003367 + ": " + e.toString(), e);
3368 }
3369 }
3370 r.stopped = true;
3371 }
3372 if (getNonConfigInstance) {
3373 try {
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07003374 r.lastNonConfigurationInstances
3375 = r.activity.retainNonConfigurationInstances();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003376 } catch (Exception e) {
3377 if (!mInstrumentation.onException(r.activity, e)) {
3378 throw new RuntimeException(
3379 "Unable to retain activity "
3380 + r.intent.getComponent().toShortString()
3381 + ": " + e.toString(), e);
3382 }
3383 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003384 }
3385 try {
3386 r.activity.mCalled = false;
Dianne Hackborn2dedce62010-04-15 14:45:25 -07003387 mInstrumentation.callActivityOnDestroy(r.activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003388 if (!r.activity.mCalled) {
3389 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003390 "Activity " + safeToComponentShortString(r.intent) +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003391 " did not call through to super.onDestroy()");
3392 }
3393 if (r.window != null) {
3394 r.window.closeAllPanels();
3395 }
3396 } catch (SuperNotCalledException e) {
3397 throw e;
3398 } catch (Exception e) {
3399 if (!mInstrumentation.onException(r.activity, e)) {
3400 throw new RuntimeException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003401 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3402 + ": " + e.toString(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 }
3404 }
3405 }
3406 mActivities.remove(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003407 StrictMode.decrementExpectedActivityCount(activityClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003408 return r;
3409 }
3410
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003411 private static String safeToComponentShortString(Intent intent) {
3412 ComponentName component = intent.getComponent();
3413 return component == null ? "[Unknown]" : component.toShortString();
3414 }
3415
Romain Guy65b345f2011-07-27 18:51:50 -07003416 private void handleDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003417 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003418 ActivityClientRecord r = performDestroyActivity(token, finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003419 configChanges, getNonConfigInstance);
3420 if (r != null) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003421 cleanUpPendingRemoveWindows(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003422 WindowManager wm = r.activity.getWindowManager();
3423 View v = r.activity.mDecor;
3424 if (v != null) {
3425 if (r.activity.mVisibleFromServer) {
3426 mNumVisibleActivities--;
3427 }
3428 IBinder wtoken = v.getWindowToken();
3429 if (r.activity.mWindowAdded) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003430 if (r.onlyLocalRequest) {
3431 // Hold off on removing this until the new activity's
3432 // window is being added.
3433 r.mPendingRemoveWindow = v;
3434 r.mPendingRemoveWindowManager = wm;
3435 } else {
3436 wm.removeViewImmediate(v);
3437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003438 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003439 if (wtoken != null && r.mPendingRemoveWindow == null) {
Jeff Brown98365d72012-08-19 20:30:52 -07003440 WindowManagerGlobal.getInstance().closeAll(wtoken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003441 r.activity.getClass().getName(), "Activity");
3442 }
3443 r.activity.mDecor = null;
3444 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003445 if (r.mPendingRemoveWindow == null) {
3446 // If we are delaying the removal of the activity window, then
3447 // we can't clean up all windows here. Note that we can't do
3448 // so later either, which means any windows that aren't closed
3449 // by the app will leak. Well we try to warning them a lot
3450 // about leaking windows, because that is a bug, so if they are
3451 // using this recreate facility then they get to live with leaks.
Jeff Brown98365d72012-08-19 20:30:52 -07003452 WindowManagerGlobal.getInstance().closeAll(token,
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003453 r.activity.getClass().getName(), "Activity");
3454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455
3456 // Mocked out contexts won't be participating in the normal
3457 // process lifecycle, but if we're running with a proper
3458 // ApplicationContext we need to have it tear down things
3459 // cleanly.
3460 Context c = r.activity.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08003461 if (c instanceof ContextImpl) {
3462 ((ContextImpl) c).scheduleFinalCleanup(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 r.activity.getClass().getName(), "Activity");
3464 }
3465 }
3466 if (finishing) {
3467 try {
3468 ActivityManagerNative.getDefault().activityDestroyed(token);
3469 } catch (RemoteException ex) {
3470 // If the system process has died, it's game over for everyone.
3471 }
3472 }
3473 }
3474
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003475 public final void requestRelaunchActivity(IBinder token,
3476 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3477 int configChanges, boolean notResumed, Configuration config,
3478 boolean fromServer) {
3479 ActivityClientRecord target = null;
3480
3481 synchronized (mPackages) {
3482 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3483 ActivityClientRecord r = mRelaunchingActivities.get(i);
3484 if (r.token == token) {
3485 target = r;
3486 if (pendingResults != null) {
3487 if (r.pendingResults != null) {
3488 r.pendingResults.addAll(pendingResults);
3489 } else {
3490 r.pendingResults = pendingResults;
3491 }
3492 }
3493 if (pendingNewIntents != null) {
3494 if (r.pendingIntents != null) {
3495 r.pendingIntents.addAll(pendingNewIntents);
3496 } else {
3497 r.pendingIntents = pendingNewIntents;
3498 }
3499 }
3500 break;
3501 }
3502 }
3503
3504 if (target == null) {
3505 target = new ActivityClientRecord();
3506 target.token = token;
3507 target.pendingResults = pendingResults;
3508 target.pendingIntents = pendingNewIntents;
3509 if (!fromServer) {
3510 ActivityClientRecord existing = mActivities.get(token);
3511 if (existing != null) {
3512 target.startsNotResumed = existing.paused;
3513 }
3514 target.onlyLocalRequest = true;
3515 }
3516 mRelaunchingActivities.add(target);
3517 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
3518 }
3519
3520 if (fromServer) {
3521 target.startsNotResumed = notResumed;
3522 target.onlyLocalRequest = false;
3523 }
3524 if (config != null) {
3525 target.createdConfig = config;
3526 }
3527 target.pendingConfigChanges |= configChanges;
3528 }
3529 }
3530
Romain Guy65b345f2011-07-27 18:51:50 -07003531 private void handleRelaunchActivity(ActivityClientRecord tmp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 // If we are getting ready to gc after going to the background, well
3533 // we are back active so skip it.
3534 unscheduleGcIdler();
3535
3536 Configuration changedConfig = null;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003537 int configChanges = 0;
Bob Leee5408332009-09-04 18:31:17 -07003538
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003539 // First: make sure we have the most recent configuration and most
3540 // recent version of the activity, or skip it if some previous call
3541 // had taken a more recent version.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003542 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003543 int N = mRelaunchingActivities.size();
3544 IBinder token = tmp.token;
3545 tmp = null;
3546 for (int i=0; i<N; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003547 ActivityClientRecord r = mRelaunchingActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003548 if (r.token == token) {
3549 tmp = r;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003550 configChanges |= tmp.pendingConfigChanges;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003551 mRelaunchingActivities.remove(i);
3552 i--;
3553 N--;
3554 }
3555 }
Bob Leee5408332009-09-04 18:31:17 -07003556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003557 if (tmp == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003558 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 return;
3560 }
Bob Leee5408332009-09-04 18:31:17 -07003561
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003562 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3563 + tmp.token + " with configChanges=0x"
3564 + Integer.toHexString(configChanges));
3565
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003566 if (mPendingConfiguration != null) {
3567 changedConfig = mPendingConfiguration;
3568 mPendingConfiguration = null;
3569 }
3570 }
Bob Leee5408332009-09-04 18:31:17 -07003571
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003572 if (tmp.createdConfig != null) {
3573 // If the activity manager is passing us its current config,
3574 // assume that is really what we want regardless of what we
3575 // may have pending.
3576 if (mConfiguration == null
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003577 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3578 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3579 if (changedConfig == null
3580 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3581 changedConfig = tmp.createdConfig;
3582 }
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003583 }
3584 }
3585
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003586 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003587 + tmp.token + ": changedConfig=" + changedConfig);
3588
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003589 // If there was a pending configuration change, execute it first.
3590 if (changedConfig != null) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003591 mCurDefaultDisplayDpi = changedConfig.densityDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -07003592 updateDefaultDensity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003593 handleConfigurationChanged(changedConfig, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 }
Bob Leee5408332009-09-04 18:31:17 -07003595
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003596 ActivityClientRecord r = mActivities.get(tmp.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003597 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 if (r == null) {
3599 return;
3600 }
Bob Leee5408332009-09-04 18:31:17 -07003601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003603 r.onlyLocalRequest = tmp.onlyLocalRequest;
Christopher Tateb70f3df2009-04-07 16:07:59 -07003604 Intent currentIntent = r.activity.mIntent;
Bob Leee5408332009-09-04 18:31:17 -07003605
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003606 r.activity.mChangingConfigurations = true;
3607
Dianne Hackborne2b04802010-12-09 09:24:55 -08003608 // Need to ensure state is saved.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003609 if (!r.paused) {
Dianne Hackborne2b04802010-12-09 09:24:55 -08003610 performPauseActivity(r.token, false, r.isPreHoneycomb());
3611 }
3612 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3613 r.state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04003614 r.state.setAllowFds(false);
Dianne Hackborne2b04802010-12-09 09:24:55 -08003615 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616 }
Bob Leee5408332009-09-04 18:31:17 -07003617
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003618 handleDestroyActivity(r.token, false, configChanges, true);
Bob Leee5408332009-09-04 18:31:17 -07003619
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003620 r.activity = null;
3621 r.window = null;
3622 r.hideForNow = false;
3623 r.nextIdle = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07003624 // Merge any pending results and pending intents; don't just replace them
3625 if (tmp.pendingResults != null) {
3626 if (r.pendingResults == null) {
3627 r.pendingResults = tmp.pendingResults;
3628 } else {
3629 r.pendingResults.addAll(tmp.pendingResults);
3630 }
3631 }
3632 if (tmp.pendingIntents != null) {
3633 if (r.pendingIntents == null) {
3634 r.pendingIntents = tmp.pendingIntents;
3635 } else {
3636 r.pendingIntents.addAll(tmp.pendingIntents);
3637 }
3638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003639 r.startsNotResumed = tmp.startsNotResumed;
Bob Leee5408332009-09-04 18:31:17 -07003640
Christopher Tateb70f3df2009-04-07 16:07:59 -07003641 handleLaunchActivity(r, currentIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003642 }
3643
Romain Guy65b345f2011-07-27 18:51:50 -07003644 private void handleRequestThumbnail(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003645 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 Bitmap thumbnail = createThumbnailBitmap(r);
3647 CharSequence description = null;
3648 try {
3649 description = r.activity.onCreateDescription();
3650 } catch (Exception e) {
3651 if (!mInstrumentation.onException(r.activity, e)) {
3652 throw new RuntimeException(
3653 "Unable to create description of activity "
3654 + r.intent.getComponent().toShortString()
3655 + ": " + e.toString(), e);
3656 }
3657 }
3658 //System.out.println("Reporting top thumbnail " + thumbnail);
3659 try {
3660 ActivityManagerNative.getDefault().reportThumbnail(
3661 token, thumbnail, description);
3662 } catch (RemoteException ex) {
3663 }
3664 }
3665
Dianne Hackborn73c14162012-09-19 15:45:06 -07003666 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 boolean allActivities, Configuration newConfig) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003668 ArrayList<ComponentCallbacks2> callbacks
3669 = new ArrayList<ComponentCallbacks2>();
Bob Leee5408332009-09-04 18:31:17 -07003670
Dianne Hackborn73c14162012-09-19 15:45:06 -07003671 synchronized (mPackages) {
3672 final int N = mAllApplications.size();
3673 for (int i=0; i<N; i++) {
3674 callbacks.add(mAllApplications.get(i));
3675 }
3676 if (mActivities.size() > 0) {
3677 for (ActivityClientRecord ar : mActivities.values()) {
3678 Activity a = ar.activity;
3679 if (a != null) {
3680 Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
3681 newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
3682 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3683 // If the activity is currently resumed, its configuration
3684 // needs to change right now.
3685 callbacks.add(a);
3686 } else if (thisConfig != null) {
3687 // Otherwise, we will tell it about the change
3688 // the next time it is resumed or shown. Note that
3689 // the activity manager may, before then, decide the
3690 // activity needs to be destroyed to handle its new
3691 // configuration.
3692 if (DEBUG_CONFIGURATION) {
3693 Slog.v(TAG, "Setting activity "
3694 + ar.activityInfo.name + " newConfig=" + thisConfig);
3695 }
3696 ar.newConfig = thisConfig;
Romain Guya998dff2012-03-23 18:58:36 -07003697 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003698 }
3699 }
3700 }
Dianne Hackborn73c14162012-09-19 15:45:06 -07003701 if (mServices.size() > 0) {
3702 for (Service service : mServices.values()) {
3703 callbacks.add(service);
3704 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 }
3706 }
3707 synchronized (mProviderMap) {
3708 if (mLocalProviders.size() > 0) {
Romain Guya998dff2012-03-23 18:58:36 -07003709 for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
3710 callbacks.add(providerClientRecord.mLocalProvider);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003711 }
3712 }
3713 }
Bob Leee5408332009-09-04 18:31:17 -07003714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003715 return callbacks;
3716 }
Bob Leee5408332009-09-04 18:31:17 -07003717
Romain Guya998dff2012-03-23 18:58:36 -07003718 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003719 // Only for Activity objects, check that they actually call up to their
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003720 // superclass implementation. ComponentCallbacks2 is an interface, so
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003721 // we check the runtime type and act accordingly.
3722 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3723 if (activity != null) {
3724 activity.mCalled = false;
3725 }
Bob Leee5408332009-09-04 18:31:17 -07003726
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003727 boolean shouldChangeConfig = false;
3728 if ((activity == null) || (activity.mCurrentConfig == null)) {
3729 shouldChangeConfig = true;
3730 } else {
Bob Leee5408332009-09-04 18:31:17 -07003731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003732 // If the new config is the same as the config this Activity
3733 // is already running with then don't bother calling
3734 // onConfigurationChanged
3735 int diff = activity.mCurrentConfig.diff(config);
3736 if (diff != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003737 // If this activity doesn't handle any of the config changes
3738 // then don't bother calling onConfigurationChanged as we're
3739 // going to destroy it.
Dianne Hackborne6676352011-06-01 16:51:20 -07003740 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003741 shouldChangeConfig = true;
3742 }
3743 }
3744 }
Bob Leee5408332009-09-04 18:31:17 -07003745
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003746 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003747 + ": shouldChangeConfig=" + shouldChangeConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003748 if (shouldChangeConfig) {
3749 cb.onConfigurationChanged(config);
Bob Leee5408332009-09-04 18:31:17 -07003750
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003751 if (activity != null) {
3752 if (!activity.mCalled) {
3753 throw new SuperNotCalledException(
3754 "Activity " + activity.getLocalClassName() +
3755 " did not call through to super.onConfigurationChanged()");
3756 }
3757 activity.mConfigChangeFlags = 0;
3758 activity.mCurrentConfig = new Configuration(config);
3759 }
3760 }
3761 }
3762
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003763 public final void applyConfigurationToResources(Configuration config) {
3764 synchronized (mPackages) {
3765 applyConfigurationToResourcesLocked(config, null);
3766 }
3767 }
3768
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003769 final boolean applyConfigurationToResourcesLocked(Configuration config,
3770 CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003771 if (mResConfiguration == null) {
3772 mResConfiguration = new Configuration();
3773 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003774 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003775 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003776 + mResConfiguration.seq + ", newSeq=" + config.seq);
Dianne Hackbornae078162010-03-18 11:29:37 -07003777 return false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003778 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003779 int changes = mResConfiguration.updateFrom(config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003780 flushDisplayMetricsLocked();
3781 DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
3782 Display.DEFAULT_DISPLAY, null);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003783
3784 if (compat != null && (mResCompatibilityInfo == null ||
3785 !mResCompatibilityInfo.equals(compat))) {
3786 mResCompatibilityInfo = compat;
3787 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
3788 | ActivityInfo.CONFIG_SCREEN_SIZE
3789 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
3790 }
Bob Leee5408332009-09-04 18:31:17 -07003791
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003792 // set it for java, this also affects newly created Resources
3793 if (config.locale != null) {
3794 Locale.setDefault(config.locale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 }
Bob Leee5408332009-09-04 18:31:17 -07003796
Jeff Browna492c3a2012-08-23 19:48:44 -07003797 Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
Bob Leee5408332009-09-04 18:31:17 -07003798
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08003799 ApplicationPackageManager.configurationChanged();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003800 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
Dianne Hackborn756220b2012-08-14 16:45:30 -07003801
3802 Configuration tmpConfig = null;
3803
3804 Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
3805 mActiveResources.entrySet().iterator();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003806 while (it.hasNext()) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07003807 Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
3808 Resources r = entry.getValue().get();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003809 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003810 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003811 + r + " config to: " + config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003812 int displayId = entry.getKey().mDisplayId;
3813 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
3814 DisplayMetrics dm = defaultDisplayMetrics;
3815 Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
3816 if (!isDefaultDisplay || overrideConfig != null) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07003817 if (tmpConfig == null) {
3818 tmpConfig = new Configuration();
3819 }
3820 tmpConfig.setTo(config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003821 if (!isDefaultDisplay) {
3822 dm = getDisplayMetricsLocked(displayId, null);
3823 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
3824 }
3825 if (overrideConfig != null) {
3826 tmpConfig.updateFrom(overrideConfig);
3827 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07003828 r.updateConfiguration(tmpConfig, dm, compat);
3829 } else {
3830 r.updateConfiguration(config, dm, compat);
3831 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003832 //Slog.i(TAG, "Updated app resources " + v.getKey()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003833 // + " " + r + ": " + r.getConfiguration());
3834 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003835 //Slog.i(TAG, "Removing old resources " + v.getKey());
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003836 it.remove();
3837 }
3838 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003839
3840 return changes != 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003841 }
Dianne Hackborn836e2622011-10-04 18:32:39 -07003842
Jeff Browna492c3a2012-08-23 19:48:44 -07003843 final void applyNonDefaultDisplayMetricsToConfigurationLocked(
3844 DisplayMetrics dm, Configuration config) {
3845 config.screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE
3846 | Configuration.SCREENLAYOUT_LONG_NO;
3847 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
3848 config.orientation = (dm.widthPixels >= dm.heightPixels) ?
3849 Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
3850 config.densityDpi = dm.densityDpi;
3851 config.screenWidthDp = (int)(dm.widthPixels / dm.density);
3852 config.screenHeightDp = (int)(dm.heightPixels / dm.density);
3853 config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
3854 config.compatScreenWidthDp = config.screenWidthDp;
3855 config.compatScreenHeightDp = config.screenHeightDp;
3856 config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
3857 }
3858
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003859 final Configuration applyCompatConfiguration(int displayDensity) {
Dianne Hackborn836e2622011-10-04 18:32:39 -07003860 Configuration config = mConfiguration;
3861 if (mCompatConfiguration == null) {
3862 mCompatConfiguration = new Configuration();
3863 }
3864 mCompatConfiguration.setTo(mConfiguration);
3865 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003866 mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration);
Dianne Hackborn836e2622011-10-04 18:32:39 -07003867 config = mCompatConfiguration;
3868 }
3869 return config;
3870 }
3871
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003872 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003873
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003874 int configDiff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003875
3876 synchronized (mPackages) {
3877 if (mPendingConfiguration != null) {
3878 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3879 config = mPendingConfiguration;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003880 mCurDefaultDisplayDpi = config.densityDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -07003881 updateDefaultDensity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003882 }
3883 mPendingConfiguration = null;
3884 }
3885
3886 if (config == null) {
3887 return;
3888 }
3889
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003890 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003891 + config);
3892
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003893 applyConfigurationToResourcesLocked(config, compat);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003894
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003895 if (mConfiguration == null) {
3896 mConfiguration = new Configuration();
3897 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003898 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003899 return;
3900 }
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003901 configDiff = mConfiguration.diff(config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003902 mConfiguration.updateFrom(config);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003903 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003904 }
Dianne Hackborn73c14162012-09-19 15:45:06 -07003905
3906 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
3907
Romain Guy65b345f2011-07-27 18:51:50 -07003908 // Cleanup hardware accelerated stuff
Jeff Brown98365d72012-08-19 20:30:52 -07003909 WindowManagerGlobal.getInstance().trimLocalMemory();
Bob Leee5408332009-09-04 18:31:17 -07003910
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003911 freeTextLayoutCachesIfNeeded(configDiff);
3912
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003913 if (callbacks != null) {
3914 final int N = callbacks.size();
3915 for (int i=0; i<N; i++) {
3916 performConfigurationChanged(callbacks.get(i), config);
3917 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 }
3919 }
3920
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003921 final void freeTextLayoutCachesIfNeeded(int configDiff) {
3922 if (configDiff != 0) {
3923 // Ask text layout engine to free its caches if there is a locale change
3924 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
3925 if (hasLocaleConfigChange) {
3926 Canvas.freeTextLayoutCaches();
3927 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
3928 }
3929 }
3930 }
3931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003932 final void handleActivityConfigurationChanged(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003933 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003934 if (r == null || r.activity == null) {
3935 return;
3936 }
Bob Leee5408332009-09-04 18:31:17 -07003937
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003938 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003939 + r.activityInfo.name);
3940
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003941 performConfigurationChanged(r.activity, mCompatConfiguration);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003942
3943 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003944 }
3945
Romain Guy7eabe552011-07-21 14:56:34 -07003946 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003947 if (start) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003948 try {
Romain Guy7eabe552011-07-21 14:56:34 -07003949 switch (profileType) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07003950 default:
3951 mProfiler.setProfiler(pcd.path, pcd.fd);
3952 mProfiler.autoStopProfiler = false;
3953 mProfiler.startProfiling();
Romain Guy7eabe552011-07-21 14:56:34 -07003954 break;
3955 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003956 } catch (RuntimeException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003957 Slog.w(TAG, "Profiling failed on path " + pcd.path
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003958 + " -- can the process access this path?");
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003959 } finally {
3960 try {
3961 pcd.fd.close();
3962 } catch (IOException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003963 Slog.w(TAG, "Failure closing profile fd", e);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003964 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003965 }
3966 } else {
Romain Guy7eabe552011-07-21 14:56:34 -07003967 switch (profileType) {
Romain Guy7eabe552011-07-21 14:56:34 -07003968 default:
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07003969 mProfiler.stopProfiling();
Romain Guy7eabe552011-07-21 14:56:34 -07003970 break;
Romain Guy7eabe552011-07-21 14:56:34 -07003971 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003972 }
3973 }
Bob Leee5408332009-09-04 18:31:17 -07003974
Romain Guya998dff2012-03-23 18:58:36 -07003975 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
Andy McFadden824c5102010-07-09 16:26:57 -07003976 if (managed) {
3977 try {
3978 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
3979 } catch (IOException e) {
3980 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
3981 + " -- can the process access this path?");
3982 } finally {
3983 try {
3984 dhd.fd.close();
3985 } catch (IOException e) {
3986 Slog.w(TAG, "Failure closing profile fd", e);
3987 }
3988 }
3989 } else {
Andy McFadden06a6b552010-07-13 16:28:09 -07003990 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
Andy McFadden824c5102010-07-09 16:26:57 -07003991 }
3992 }
3993
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003994 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
3995 boolean hasPkgInfo = false;
3996 if (packages != null) {
3997 for (int i=packages.length-1; i>=0; i--) {
3998 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
3999 if (!hasPkgInfo) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004000 WeakReference<LoadedApk> ref;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07004001 ref = mPackages.get(packages[i]);
4002 if (ref != null && ref.get() != null) {
4003 hasPkgInfo = true;
4004 } else {
4005 ref = mResourcePackages.get(packages[i]);
4006 if (ref != null && ref.get() != null) {
4007 hasPkgInfo = true;
4008 }
4009 }
4010 }
4011 mPackages.remove(packages[i]);
4012 mResourcePackages.remove(packages[i]);
4013 }
4014 }
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08004015 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07004016 hasPkgInfo);
4017 }
4018
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004019 final void handleLowMemory() {
Dianne Hackborn73c14162012-09-19 15:45:06 -07004020 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
Bob Leee5408332009-09-04 18:31:17 -07004021
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004022 final int N = callbacks.size();
4023 for (int i=0; i<N; i++) {
4024 callbacks.get(i).onLowMemory();
4025 }
4026
Chris Tatece229052009-03-25 16:44:52 -07004027 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4028 if (Process.myUid() != Process.SYSTEM_UID) {
4029 int sqliteReleased = SQLiteDatabase.releaseMemory();
4030 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4031 }
Bob Leee5408332009-09-04 18:31:17 -07004032
Mike Reedcaf0df12009-04-27 14:32:05 -04004033 // Ask graphics to free up as much as possible (font/image caches)
4034 Canvas.freeCaches();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004035
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07004036 // Ask text layout engine to free also as much as possible
4037 Canvas.freeTextLayoutCaches();
4038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004039 BinderInternal.forceGc("mem");
4040 }
4041
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004042 final void handleTrimMemory(int level) {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07004043 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004044
Jeff Brown98365d72012-08-19 20:30:52 -07004045 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
Romain Guy19f86e82012-04-23 15:19:07 -07004046 windowManager.startTrimMemory(level);
4047
Dianne Hackborn73c14162012-09-19 15:45:06 -07004048 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004049
4050 final int N = callbacks.size();
Romain Guya998dff2012-03-23 18:58:36 -07004051 for (int i = 0; i < N; i++) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004052 callbacks.get(i).onTrimMemory(level);
4053 }
Romain Guy19f86e82012-04-23 15:19:07 -07004054
Jeff Brown98365d72012-08-19 20:30:52 -07004055 windowManager.endTrimMemory();
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004056 }
4057
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004058 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004059 if (Process.isIsolated()) {
4060 // Isolated processes aren't going to do UI.
4061 return;
4062 }
Romain Guya9582652011-11-10 14:20:10 -08004063 try {
4064 int uid = Process.myUid();
4065 String[] packages = getPackageManager().getPackagesForUid(uid);
4066
4067 // If there are several packages in this application we won't
4068 // initialize the graphics disk caches
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004069 if (packages != null && packages.length == 1) {
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004070 HardwareRenderer.setupDiskCache(cacheDir);
4071 RenderScript.setupDiskCache(cacheDir);
Romain Guya9582652011-11-10 14:20:10 -08004072 }
4073 } catch (RemoteException e) {
4074 // Ignore
4075 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07004076 }
4077
4078 private void updateDefaultDensity() {
4079 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4080 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4081 && !mDensityCompatMode) {
4082 Slog.i(TAG, "Switching default density from "
4083 + DisplayMetrics.DENSITY_DEVICE + " to "
4084 + mCurDefaultDisplayDpi);
4085 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4086 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4087 }
4088 }
4089
Romain Guy65b345f2011-07-27 18:51:50 -07004090 private void handleBindApplication(AppBindData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004091 mBoundApplication = data;
4092 mConfiguration = new Configuration(data.config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07004093 mCompatConfiguration = new Configuration(data.config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004094
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004095 mProfiler = new Profiler();
4096 mProfiler.profileFile = data.initProfileFile;
4097 mProfiler.profileFd = data.initProfileFd;
4098 mProfiler.autoStopProfiler = data.initAutoStopProfiler;
4099
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 // send up app name; do this *before* waiting for debugger
Christopher Tate8ee038d2009-11-06 11:30:20 -08004101 Process.setArgV0(data.processName);
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004102 android.ddm.DdmHandleAppName.setAppName(data.processName,
4103 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004104
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004105 if (data.persistent) {
4106 // Persistent processes on low-memory devices do not get to
4107 // use hardware accelerated drawing, since this can add too much
4108 // overhead to the process.
Jeff Brown98365d72012-08-19 20:30:52 -07004109 if (!ActivityManager.isHighEndGfx()) {
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004110 HardwareRenderer.disable(false);
4111 }
4112 }
Romain Guya9582652011-11-10 14:20:10 -08004113
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004114 if (mProfiler.profileFd != null) {
4115 mProfiler.startProfiling();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004116 }
4117
Joe Onoratod630f102011-03-17 18:42:26 -07004118 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4119 // implementation to use the pool executor. Normally, we use the
4120 // serialized executor as the default. This has to happen in the
4121 // main thread so the main looper is set right.
Dianne Hackborn81e92762011-10-09 16:00:21 -07004122 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
Joe Onoratod630f102011-03-17 18:42:26 -07004123 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4124 }
4125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004126 /*
4127 * Before spawning a new process, reset the time zone to be the system time zone.
4128 * This needs to be done because the system time zone could have changed after the
4129 * the spawning of this process. Without doing this this process would have the incorrect
4130 * system time zone.
4131 */
4132 TimeZone.setDefault(null);
4133
4134 /*
4135 * Initialize the default locale in this process for the reasons we set the time zone.
4136 */
4137 Locale.setDefault(data.config.locale);
4138
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07004139 /*
4140 * Update the system configuration since its preloaded and might not
4141 * reflect configuration changes. The configuration object passed
4142 * in AppBindData can be safely assumed to be up to date
4143 */
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004144 applyConfigurationToResourcesLocked(data.config, data.compatInfo);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07004145 mCurDefaultDisplayDpi = data.config.densityDpi;
4146 applyCompatConfiguration(mCurDefaultDisplayDpi);
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07004147
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004148 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004149
Dianne Hackborndde331c2012-08-03 14:01:57 -07004150 /**
4151 * Switch this process to density compatibility mode if needed.
4152 */
4153 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4154 == 0) {
4155 mDensityCompatMode = true;
4156 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4157 }
4158 updateDefaultDensity();
4159
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004160 final ContextImpl appContext = new ContextImpl();
4161 appContext.init(data.info, null, this);
Amith Yamasani11de39a2012-08-17 18:00:52 -07004162 if (!Process.isIsolated()) {
4163 final File cacheDir = appContext.getCacheDir();
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004164
Amith Yamasani92d57052012-08-23 10:07:52 -07004165 if (cacheDir != null) {
4166 // Provide a usable directory for temporary files
4167 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4168
4169 setupGraphicsSupport(data.info, cacheDir);
4170 } else {
4171 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4172 }
Amith Yamasani11de39a2012-08-17 18:00:52 -07004173 }
Dianne Hackborn96e240f2009-07-26 17:42:30 -07004174 /**
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07004175 * For system applications on userdebug/eng builds, log stack
4176 * traces of disk and network access to dropbox for analysis.
4177 */
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07004178 if ((data.appInfo.flags &
4179 (ApplicationInfo.FLAG_SYSTEM |
Brad Fitzpatrick50d66f92010-09-13 21:29:05 -07004180 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4181 StrictMode.conditionallyEnableDebugLogging();
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07004182 }
4183
4184 /**
Brad Fitzpatrickb6e18412010-10-28 14:50:05 -07004185 * For apps targetting SDK Honeycomb or later, we don't allow
4186 * network usage on the main event loop / UI thread.
4187 *
4188 * Note to those grepping: this is what ultimately throws
4189 * NetworkOnMainThreadException ...
4190 */
4191 if (data.appInfo.targetSdkVersion > 9) {
4192 StrictMode.enableDeathOnNetwork();
4193 }
4194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004195 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4196 // XXX should have option to change the port.
4197 Debug.changeDebugPort(8100);
4198 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004199 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004200 + " is waiting for the debugger on port 8100...");
4201
4202 IActivityManager mgr = ActivityManagerNative.getDefault();
4203 try {
4204 mgr.showWaitingForDebugger(mAppThread, true);
4205 } catch (RemoteException ex) {
4206 }
4207
4208 Debug.waitForDebugger();
4209
4210 try {
4211 mgr.showWaitingForDebugger(mAppThread, false);
4212 } catch (RemoteException ex) {
4213 }
4214
4215 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004216 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004217 + " can be debugged on port 8100...");
4218 }
4219 }
4220
Siva Velusamy92a8b222012-03-09 16:24:04 -08004221 // Enable OpenGL tracing if required
4222 if (data.enableOpenGlTrace) {
4223 GLUtils.enableTracing();
4224 }
4225
Robert Greenwalt434203a2010-10-11 16:00:27 -07004226 /**
4227 * Initialize the default http proxy in this process for the reasons we set the time zone.
4228 */
4229 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
Dianne Hackbornd4d32c52011-11-08 17:33:59 -08004230 if (b != null) {
4231 // In pre-boot mode (doing initial launch to collect password), not
4232 // all system is up. This includes the connectivity service, so don't
4233 // crash if we can't get it.
4234 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4235 try {
4236 ProxyProperties proxyProperties = service.getProxy();
4237 Proxy.setHttpProxySystemProperty(proxyProperties);
4238 } catch (RemoteException e) {}
4239 }
Robert Greenwalt434203a2010-10-11 16:00:27 -07004240
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 if (data.instrumentationName != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004242 InstrumentationInfo ii = null;
4243 try {
4244 ii = appContext.getPackageManager().
4245 getInstrumentationInfo(data.instrumentationName, 0);
4246 } catch (PackageManager.NameNotFoundException e) {
4247 }
4248 if (ii == null) {
4249 throw new RuntimeException(
4250 "Unable to find instrumentation info for: "
4251 + data.instrumentationName);
4252 }
4253
4254 mInstrumentationAppDir = ii.sourceDir;
Brian Carlstromd893a892012-04-01 21:30:26 -07004255 mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004256 mInstrumentationAppPackage = ii.packageName;
4257 mInstrumentedAppDir = data.info.getAppDir();
Brian Carlstromd893a892012-04-01 21:30:26 -07004258 mInstrumentedAppLibraryDir = data.info.getLibDir();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004259
4260 ApplicationInfo instrApp = new ApplicationInfo();
4261 instrApp.packageName = ii.packageName;
4262 instrApp.sourceDir = ii.sourceDir;
4263 instrApp.publicSourceDir = ii.publicSourceDir;
4264 instrApp.dataDir = ii.dataDir;
Kenny Root85387d72010-08-26 10:13:11 -07004265 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004266 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004267 appContext.getClassLoader(), false, true);
Dianne Hackborn21556372010-02-04 16:34:40 -08004268 ContextImpl instrContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004269 instrContext.init(pi, null, this);
4270
4271 try {
4272 java.lang.ClassLoader cl = instrContext.getClassLoader();
4273 mInstrumentation = (Instrumentation)
4274 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4275 } catch (Exception e) {
4276 throw new RuntimeException(
4277 "Unable to instantiate instrumentation "
4278 + data.instrumentationName + ": " + e.toString(), e);
4279 }
4280
4281 mInstrumentation.init(this, instrContext, appContext,
4282 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
4283
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004284 if (mProfiler.profileFile != null && !ii.handleProfiling
4285 && mProfiler.profileFd == null) {
4286 mProfiler.handlingProfiling = true;
4287 File file = new File(mProfiler.profileFile);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004288 file.getParentFile().mkdirs();
4289 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4290 }
4291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004292 } else {
4293 mInstrumentation = new Instrumentation();
4294 }
4295
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08004296 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
Dianne Hackbornde398512011-01-18 18:45:21 -08004297 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08004298 }
4299
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004300 // Allow disk access during application and provider setup. This could
Jeff Sharkey7c501672012-02-28 12:08:37 -08004301 // block processing ordered broadcasts, but later processing would
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004302 // probably end up doing the same disk access.
Jeff Sharkey7c501672012-02-28 12:08:37 -08004303 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 try {
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004305 // If the app is being launched for full backup or restore, bring it up in
4306 // a restricted environment with the base application class.
4307 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4308 mInitialApplication = app;
Jeff Sharkey7c501672012-02-28 12:08:37 -08004309
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004310 // don't bring up providers in restricted mode; they may depend on the
4311 // app's custom Application class
4312 if (!data.restrictedBackupMode) {
4313 List<ProviderInfo> providers = data.providers;
4314 if (providers != null) {
4315 installContentProviders(app, providers);
4316 // For process that contains content providers, we want to
4317 // ensure that the JIT is enabled "at some point".
4318 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4319 }
4320 }
4321
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004322 // Do this after providers, since instrumentation tests generally start their
4323 // test thread at this point, and we don't want that racing.
4324 try {
4325 mInstrumentation.onCreate(data.instrumentationArgs);
4326 }
4327 catch (Exception e) {
4328 throw new RuntimeException(
4329 "Exception thrown in onCreate() of "
4330 + data.instrumentationName + ": " + e.toString(), e);
4331 }
4332
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004333 try {
4334 mInstrumentation.callApplicationOnCreate(app);
4335 } catch (Exception e) {
4336 if (!mInstrumentation.onException(app, e)) {
4337 throw new RuntimeException(
4338 "Unable to create application " + app.getClass().getName()
4339 + ": " + e.toString(), e);
4340 }
4341 }
4342 } finally {
4343 StrictMode.setThreadPolicy(savedPolicy);
4344 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004345 }
4346
4347 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4348 IActivityManager am = ActivityManagerNative.getDefault();
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004349 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4350 && mProfiler.profileFd == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004351 Debug.stopMethodTracing();
4352 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004353 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004354 // + ", app thr: " + mAppThread);
4355 try {
4356 am.finishInstrumentation(mAppThread, resultCode, results);
4357 } catch (RemoteException ex) {
4358 }
4359 }
4360
Romain Guy65b345f2011-07-27 18:51:50 -07004361 private void installContentProviders(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 Context context, List<ProviderInfo> providers) {
4363 final ArrayList<IActivityManager.ContentProviderHolder> results =
4364 new ArrayList<IActivityManager.ContentProviderHolder>();
4365
Romain Guya998dff2012-03-23 18:58:36 -07004366 for (ProviderInfo cpi : providers) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004367 StringBuilder buf = new StringBuilder(128);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07004368 buf.append("Pub ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004369 buf.append(cpi.authority);
4370 buf.append(": ");
4371 buf.append(cpi.name);
4372 Log.i(TAG, buf.toString());
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004373 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4374 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4375 if (cph != null) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004376 cph.noReleaseNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 results.add(cph);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004378 }
4379 }
4380
4381 try {
4382 ActivityManagerNative.getDefault().publishContentProviders(
4383 getApplicationThread(), results);
4384 } catch (RemoteException ex) {
4385 }
4386 }
4387
Jeff Sharkey6d515712012-09-20 16:06:08 -07004388 public final IContentProvider acquireProvider(
4389 Context c, String auth, int userId, boolean stable) {
4390 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004391 if (provider != null) {
4392 return provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004393 }
4394
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004395 // There is a possible race here. Another thread may try to acquire
4396 // the same provider at the same time. When this happens, we want to ensure
4397 // that the first one wins.
4398 // Note that we cannot hold the lock while acquiring and installing the
4399 // provider since it might take a long time to run and it could also potentially
4400 // be re-entrant in the case where the provider is in the same process.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004401 IActivityManager.ContentProviderHolder holder = null;
4402 try {
4403 holder = ActivityManagerNative.getDefault().getContentProvider(
Jeff Sharkey6d515712012-09-20 16:06:08 -07004404 getApplicationThread(), auth, userId, stable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004405 } catch (RemoteException ex) {
4406 }
4407 if (holder == null) {
Jeff Sharkey6d515712012-09-20 16:06:08 -07004408 Slog.e(TAG, "Failed to find provider info for " + auth);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409 return null;
4410 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004412 // Install provider will increment the reference count for us, and break
4413 // any ties in the race.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004414 holder = installProvider(c, holder, holder.info,
4415 true /*noisy*/, holder.noReleaseNeeded, stable);
4416 return holder.provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004417 }
4418
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004419 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4420 if (stable) {
4421 prc.stableCount += 1;
4422 if (prc.stableCount == 1) {
4423 // We are acquiring a new stable reference on the provider.
4424 int unstableDelta;
4425 if (prc.removePending) {
4426 // We have a pending remove operation, which is holding the
4427 // last unstable reference. At this point we are converting
4428 // that unstable reference to our new stable reference.
4429 unstableDelta = -1;
4430 // Cancel the removal of the provider.
4431 if (DEBUG_PROVIDER) {
4432 Slog.v(TAG, "incProviderRef: stable "
4433 + "snatched provider from the jaws of death");
4434 }
4435 prc.removePending = false;
4436 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4437 } else {
4438 unstableDelta = 0;
4439 }
4440 try {
4441 if (DEBUG_PROVIDER) {
4442 Slog.v(TAG, "incProviderRef Now stable - "
4443 + prc.holder.info.name + ": unstableDelta="
4444 + unstableDelta);
4445 }
4446 ActivityManagerNative.getDefault().refContentProvider(
4447 prc.holder.connection, 1, unstableDelta);
4448 } catch (RemoteException e) {
4449 //do nothing content provider object is dead any way
4450 }
4451 }
4452 } else {
4453 prc.unstableCount += 1;
4454 if (prc.unstableCount == 1) {
4455 // We are acquiring a new unstable reference on the provider.
4456 if (prc.removePending) {
4457 // Oh look, we actually have a remove pending for the
4458 // provider, which is still holding the last unstable
4459 // reference. We just need to cancel that to take new
4460 // ownership of the reference.
4461 if (DEBUG_PROVIDER) {
4462 Slog.v(TAG, "incProviderRef: unstable "
4463 + "snatched provider from the jaws of death");
4464 }
4465 prc.removePending = false;
4466 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4467 } else {
4468 // First unstable ref, increment our count in the
4469 // activity manager.
4470 try {
4471 if (DEBUG_PROVIDER) {
4472 Slog.v(TAG, "incProviderRef: Now unstable - "
4473 + prc.holder.info.name);
4474 }
4475 ActivityManagerNative.getDefault().refContentProvider(
4476 prc.holder.connection, 0, 1);
4477 } catch (RemoteException e) {
4478 //do nothing content provider object is dead any way
4479 }
4480 }
4481 }
4482 }
4483 }
4484
Jeff Sharkey6d515712012-09-20 16:06:08 -07004485 public final IContentProvider acquireExistingProvider(
4486 Context c, String auth, int userId, boolean stable) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004487 synchronized (mProviderMap) {
Jeff Sharkey6d515712012-09-20 16:06:08 -07004488 final ProviderKey key = new ProviderKey(auth, userId);
4489 final ProviderClientRecord pr = mProviderMap.get(key);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004490 if (pr == null) {
4491 return null;
4492 }
4493
4494 IContentProvider provider = pr.mProvider;
4495 IBinder jBinder = provider.asBinder();
4496
4497 // Only increment the ref count if we have one. If we don't then the
4498 // provider is not reference counted and never needs to be released.
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07004499 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004500 if (prc != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004501 incProviderRefLocked(prc, stable);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004502 }
4503 return provider;
4504 }
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07004505 }
4506
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004507 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4508 if (provider == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 return false;
4510 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004512 IBinder jBinder = provider.asBinder();
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004513 synchronized (mProviderMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004515 if (prc == null) {
4516 // The provider has no ref count, no release is needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004517 return false;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004518 }
4519
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004520 boolean lastRef = false;
4521 if (stable) {
4522 if (prc.stableCount == 0) {
4523 if (DEBUG_PROVIDER) Slog.v(TAG,
4524 "releaseProvider: stable ref count already 0, how?");
4525 return false;
4526 }
4527 prc.stableCount -= 1;
4528 if (prc.stableCount == 0) {
4529 // What we do at this point depends on whether there are
4530 // any unstable refs left: if there are, we just tell the
4531 // activity manager to decrement its stable count; if there
4532 // aren't, we need to enqueue this provider to be removed,
4533 // and convert to holding a single unstable ref while
4534 // doing so.
4535 lastRef = prc.unstableCount == 0;
4536 try {
4537 if (DEBUG_PROVIDER) {
4538 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4539 + lastRef + " - " + prc.holder.info.name);
4540 }
4541 ActivityManagerNative.getDefault().refContentProvider(
4542 prc.holder.connection, -1, lastRef ? 1 : 0);
4543 } catch (RemoteException e) {
4544 //do nothing content provider object is dead any way
4545 }
4546 }
4547 } else {
4548 if (prc.unstableCount == 0) {
4549 if (DEBUG_PROVIDER) Slog.v(TAG,
4550 "releaseProvider: unstable ref count already 0, how?");
4551 return false;
4552 }
4553 prc.unstableCount -= 1;
4554 if (prc.unstableCount == 0) {
4555 // If this is the last reference, we need to enqueue
4556 // this provider to be removed instead of telling the
4557 // activity manager to remove it at this point.
4558 lastRef = prc.stableCount == 0;
4559 if (!lastRef) {
4560 try {
4561 if (DEBUG_PROVIDER) {
4562 Slog.v(TAG, "releaseProvider: No longer unstable - "
4563 + prc.holder.info.name);
4564 }
4565 ActivityManagerNative.getDefault().refContentProvider(
4566 prc.holder.connection, 0, -1);
4567 } catch (RemoteException e) {
4568 //do nothing content provider object is dead any way
4569 }
4570 }
4571 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004572 }
4573
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004574 if (lastRef) {
4575 if (!prc.removePending) {
4576 // Schedule the actual remove asynchronously, since we don't know the context
4577 // this will be called in.
4578 // TODO: it would be nice to post a delayed message, so
4579 // if we come back and need the same provider quickly
4580 // we will still have it available.
4581 if (DEBUG_PROVIDER) {
4582 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4583 + prc.holder.info.name);
4584 }
4585 prc.removePending = true;
4586 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4587 mH.sendMessage(msg);
4588 } else {
4589 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4590 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004591 }
4592 return true;
4593 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004594 }
4595
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004596 final void completeRemoveProvider(ProviderRefCount prc) {
4597 synchronized (mProviderMap) {
4598 if (!prc.removePending) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004599 // There was a race! Some other client managed to acquire
4600 // the provider before the removal was completed.
4601 // Abort the removal. We will do it later.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004602 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004603 + "provider still in use");
4604 return;
4605 }
4606
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004607 final IBinder jBinder = prc.holder.provider.asBinder();
4608 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4609 if (existingPrc == prc) {
4610 mProviderRefCountMap.remove(jBinder);
4611 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004612
4613 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
4614 while (iter.hasNext()) {
4615 ProviderClientRecord pr = iter.next();
4616 IBinder myBinder = pr.mProvider.asBinder();
4617 if (myBinder == jBinder) {
4618 iter.remove();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004619 }
4620 }
4621 }
4622
4623 try {
4624 if (DEBUG_PROVIDER) {
4625 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4626 + "removeContentProvider(" + prc.holder.info.name + ")");
4627 }
4628 ActivityManagerNative.getDefault().removeContentProvider(
4629 prc.holder.connection, false);
4630 } catch (RemoteException e) {
4631 //do nothing content provider object is dead any way
4632 }
4633 }
4634
4635 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4636 synchronized(mProviderMap) {
4637 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4638 if (prc != null) {
4639 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4640 + provider + " " + prc.holder.info.name);
4641 mProviderRefCountMap.remove(provider);
4642 if (prc.client != null && prc.client.mNames != null) {
4643 for (String name : prc.client.mNames) {
4644 ProviderClientRecord pr = mProviderMap.get(name);
4645 if (pr != null && pr.mProvider.asBinder() == provider) {
4646 Slog.i(TAG, "Removing dead content provider: " + name);
4647 mProviderMap.remove(name);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004648 }
4649 }
4650 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004651 if (fromClient) {
4652 // We found out about this due to execution in our client
4653 // code. Tell the activity manager about it now, to ensure
4654 // that the next time we go to do anything with the provider
4655 // it knows it is dead (so we don't race with its death
4656 // notification).
4657 try {
4658 ActivityManagerNative.getDefault().unstableProviderDied(
4659 prc.holder.connection);
4660 } catch (RemoteException e) {
4661 //do nothing content provider object is dead any way
4662 }
4663 }
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004664 }
4665 }
4666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004667
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004668 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
Jeff Sharkey6d515712012-09-20 16:06:08 -07004669 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4670 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4671 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4672
4673 final ProviderClientRecord pcr = new ProviderClientRecord(
4674 auths, provider, localProvider, holder);
4675 for (String auth : auths) {
4676 final ProviderKey key = new ProviderKey(auth, userId);
4677 final ProviderClientRecord existing = mProviderMap.get(key);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004678 if (existing != null) {
4679 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
Jeff Sharkey6d515712012-09-20 16:06:08 -07004680 + " already published as " + auth);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004681 } else {
Jeff Sharkey6d515712012-09-20 16:06:08 -07004682 mProviderMap.put(key, pcr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004683 }
4684 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004685 return pcr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004686 }
4687
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004688 /**
4689 * Installs the provider.
4690 *
4691 * Providers that are local to the process or that come from the system server
4692 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4693 * Other remote providers are reference counted. The initial reference count
4694 * for all reference counted providers is one. Providers that are not reference
4695 * counted do not have a reference count (at all).
4696 *
4697 * This method detects when a provider has already been installed. When this happens,
4698 * it increments the reference count of the existing provider (if appropriate)
4699 * and returns the existing provider. This can happen due to concurrent
4700 * attempts to acquire the same provider.
4701 */
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004702 private IActivityManager.ContentProviderHolder installProvider(Context context,
4703 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4704 boolean noisy, boolean noReleaseNeeded, boolean stable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004705 ContentProvider localProvider = null;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004706 IContentProvider provider;
Dianne Hackborn5f48fca2012-05-30 11:06:31 -07004707 if (holder == null || holder.provider == null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004708 if (DEBUG_PROVIDER || noisy) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004709 Slog.d(TAG, "Loading provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004710 + info.name);
4711 }
4712 Context c = null;
4713 ApplicationInfo ai = info.applicationInfo;
4714 if (context.getPackageName().equals(ai.packageName)) {
4715 c = context;
4716 } else if (mInitialApplication != null &&
4717 mInitialApplication.getPackageName().equals(ai.packageName)) {
4718 c = mInitialApplication;
4719 } else {
4720 try {
4721 c = context.createPackageContext(ai.packageName,
4722 Context.CONTEXT_INCLUDE_CODE);
4723 } catch (PackageManager.NameNotFoundException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07004724 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004725 }
4726 }
4727 if (c == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004728 Slog.w(TAG, "Unable to get context for package " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004729 ai.packageName +
4730 " while loading content provider " +
4731 info.name);
4732 return null;
4733 }
4734 try {
4735 final java.lang.ClassLoader cl = c.getClassLoader();
4736 localProvider = (ContentProvider)cl.
4737 loadClass(info.name).newInstance();
4738 provider = localProvider.getIContentProvider();
4739 if (provider == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004740 Slog.e(TAG, "Failed to instantiate class " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004741 info.name + " from sourceDir " +
4742 info.applicationInfo.sourceDir);
4743 return null;
4744 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004745 if (DEBUG_PROVIDER) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004746 TAG, "Instantiating local provider " + info.name);
4747 // XXX Need to create the correct context for this provider.
4748 localProvider.attachInfo(c, info);
4749 } catch (java.lang.Exception e) {
4750 if (!mInstrumentation.onException(null, e)) {
4751 throw new RuntimeException(
4752 "Unable to get provider " + info.name
4753 + ": " + e.toString(), e);
4754 }
4755 return null;
4756 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004757 } else {
4758 provider = holder.provider;
4759 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004760 + info.name);
4761 }
4762
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004763 IActivityManager.ContentProviderHolder retHolder;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004764
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004765 synchronized (mProviderMap) {
4766 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4767 + " / " + info.name);
4768 IBinder jBinder = provider.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004769 if (localProvider != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004770 ComponentName cname = new ComponentName(info.packageName, info.name);
4771 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004772 if (pr != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004773 if (DEBUG_PROVIDER) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004774 Slog.v(TAG, "installProvider: lost the race, "
4775 + "using existing local provider");
4776 }
4777 provider = pr.mProvider;
4778 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004779 holder = new IActivityManager.ContentProviderHolder(info);
4780 holder.provider = provider;
4781 holder.noReleaseNeeded = true;
4782 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004783 mLocalProviders.put(jBinder, pr);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004784 mLocalProvidersByName.put(cname, pr);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004785 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004786 retHolder = pr.mHolder;
4787 } else {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004788 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4789 if (prc != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004790 if (DEBUG_PROVIDER) {
4791 Slog.v(TAG, "installProvider: lost the race, updating ref count");
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004792 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004793 // We need to transfer our new reference to the existing
4794 // ref count, releasing the old one... but only if
4795 // release is needed (that is, it is not running in the
4796 // system process).
4797 if (!noReleaseNeeded) {
4798 incProviderRefLocked(prc, stable);
4799 try {
4800 ActivityManagerNative.getDefault().removeContentProvider(
4801 holder.connection, stable);
4802 } catch (RemoteException e) {
4803 //do nothing content provider object is dead any way
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004804 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004805 }
4806 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004807 ProviderClientRecord client = installProviderAuthoritiesLocked(
4808 provider, localProvider, holder);
4809 if (noReleaseNeeded) {
4810 prc = new ProviderRefCount(holder, client, 1000, 1000);
4811 } else {
4812 prc = stable
4813 ? new ProviderRefCount(holder, client, 1, 0)
4814 : new ProviderRefCount(holder, client, 0, 1);
4815 }
4816 mProviderRefCountMap.put(jBinder, prc);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004817 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004818 retHolder = prc.holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004819 }
4820 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004821
4822 return retHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004823 }
4824
Romain Guy65b345f2011-07-27 18:51:50 -07004825 private void attach(boolean system) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004826 sThreadLocal.set(this);
4827 mSystemThread = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004828 if (!system) {
Dianne Hackborn6dd005b2011-07-18 13:22:50 -07004829 ViewRootImpl.addFirstDrawHandler(new Runnable() {
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08004830 public void run() {
4831 ensureJitEnabled();
4832 }
4833 });
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004834 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
4835 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 RuntimeInit.setApplicationObject(mAppThread.asBinder());
4837 IActivityManager mgr = ActivityManagerNative.getDefault();
4838 try {
4839 mgr.attachApplication(mAppThread);
4840 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07004841 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 }
4843 } else {
4844 // Don't set application object here -- if the system crashes,
4845 // we can't display an alert, we just want to die die die.
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004846 android.ddm.DdmHandleAppName.setAppName("system_process",
4847 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004848 try {
4849 mInstrumentation = new Instrumentation();
Dianne Hackborn21556372010-02-04 16:34:40 -08004850 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004851 context.init(getSystemContext().mPackageInfo, null, this);
4852 Application app = Instrumentation.newApplication(Application.class, context);
4853 mAllApplications.add(app);
4854 mInitialApplication = app;
4855 app.onCreate();
4856 } catch (Exception e) {
4857 throw new RuntimeException(
4858 "Unable to instantiate Application():" + e.toString(), e);
4859 }
4860 }
Geremy Condrab7faaf42012-09-19 18:07:42 -07004861
4862 // add dropbox logging to libcore
4863 DropBox.setReporter(new DropBoxReporter());
4864
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004865 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004866 public void onConfigurationChanged(Configuration newConfig) {
4867 synchronized (mPackages) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004868 // We need to apply this change to the resources
4869 // immediately, because upon returning the view
4870 // hierarchy will be informed about it.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004871 if (applyConfigurationToResourcesLocked(newConfig, null)) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004872 // This actually changed the resources! Tell
4873 // everyone about it.
4874 if (mPendingConfiguration == null ||
4875 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
4876 mPendingConfiguration = newConfig;
4877
4878 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
4879 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004880 }
4881 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004882 }
4883 public void onLowMemory() {
4884 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004885 public void onTrimMemory(int level) {
4886 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004887 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004888 }
4889
Romain Guy5e9120d2012-01-30 12:17:22 -08004890 public static ActivityThread systemMain() {
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004891 HardwareRenderer.disable(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892 ActivityThread thread = new ActivityThread();
4893 thread.attach(true);
4894 return thread;
4895 }
4896
Jeff Brown10e89712011-07-08 18:52:57 -07004897 public final void installSystemProviders(List<ProviderInfo> providers) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004898 if (providers != null) {
Jeff Brown10e89712011-07-08 18:52:57 -07004899 installContentProviders(mInitialApplication, providers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004900 }
4901 }
4902
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004903 public int getIntCoreSetting(String key, int defaultValue) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08004904 synchronized (mPackages) {
4905 if (mCoreSettings != null) {
4906 return mCoreSettings.getInt(key, defaultValue);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004907 } else {
4908 return defaultValue;
4909 }
4910 }
4911 }
4912
Geremy Condra69689a72012-09-11 16:57:17 -07004913 private static class EventLoggingReporter implements EventLogger.Reporter {
4914 @Override
4915 public void report (int code, Object... list) {
4916 EventLog.writeEvent(code, list);
4917 }
4918 }
4919
Geremy Condrab7faaf42012-09-19 18:07:42 -07004920 private class DropBoxReporter implements DropBox.Reporter {
4921
4922 private DropBoxManager dropBox;
4923
4924 public DropBoxReporter() {
4925 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
4926 }
4927
4928 @Override
4929 public void addData(String tag, byte[] data, int flags) {
4930 dropBox.addData(tag, data, flags);
4931 }
4932
4933 @Override
4934 public void addText(String tag, String data) {
4935 dropBox.addText(tag, data);
4936 }
4937 }
4938
Romain Guy65b345f2011-07-27 18:51:50 -07004939 public static void main(String[] args) {
Bob Leee5408332009-09-04 18:31:17 -07004940 SamplingProfilerIntegration.start();
4941
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -08004942 // CloseGuard defaults to true and can be quite spammy. We
4943 // disable it here, but selectively enable it later (via
4944 // StrictMode) on debug builds, but using DropBox, not logs.
4945 CloseGuard.setEnabled(false);
4946
Jeff Sharkeyb049e212012-09-07 23:16:01 -07004947 Environment.initForCurrentUser();
4948
Geremy Condra69689a72012-09-11 16:57:17 -07004949 // Set the reporter for event logging in libcore
4950 EventLogger.setReporter(new EventLoggingReporter());
4951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004952 Process.setArgV0("<pre-initialized>");
4953
4954 Looper.prepareMainLooper();
4955
4956 ActivityThread thread = new ActivityThread();
4957 thread.attach(false);
4958
Vairavan Srinivasan7335cfd2012-08-18 18:36:03 -07004959 if (sMainThreadHandler == null) {
4960 sMainThreadHandler = thread.getHandler();
4961 }
4962
Romain Guy5e9120d2012-01-30 12:17:22 -08004963 AsyncTask.init();
4964
Dianne Hackborn287952c2010-09-22 22:34:31 -07004965 if (false) {
4966 Looper.myLooper().setMessageLogging(new
4967 LogPrinter(Log.DEBUG, "ActivityThread"));
4968 }
4969
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004970 Looper.loop();
4971
Jeff Brown10e89712011-07-08 18:52:57 -07004972 throw new RuntimeException("Main thread loop unexpectedly exited");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004973 }
4974}