blob: 640f0836124ea104f0d5bc57daf08e313d7709a9 [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;
Jeff Brownefd43bd2012-09-21 17:02:35 -070068import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070069import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070070import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.util.AndroidRuntimeException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.util.DisplayMetrics;
73import android.util.EventLog;
74import android.util.Log;
Dianne Hackborn287952c2010-09-22 22:34:31 -070075import android.util.LogPrinter;
Jeff Brown6754ba22011-12-14 20:20:01 -080076import android.util.PrintWriterPrinter;
Dianne Hackbornc9421ba2010-03-11 22:23:46 -080077import android.util.Slog;
Jeff Brownd32460c2012-07-20 16:15:36 -070078import android.view.CompatibilityInfoHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import android.view.Display;
Romain Guy52339202010-09-03 16:04:46 -070080import android.view.HardwareRenderer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import android.view.View;
82import android.view.ViewDebug;
83import android.view.ViewManager;
Dianne Hackborn6dd005b2011-07-18 13:22:50 -070084import android.view.ViewRootImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import android.view.Window;
86import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -070087import android.view.WindowManagerGlobal;
Jason Samsa6f338c2012-02-24 16:22:16 -080088import android.renderscript.RenderScript;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
90import com.android.internal.os.BinderInternal;
91import com.android.internal.os.RuntimeInit;
Bob Leee5408332009-09-04 18:31:17 -070092import com.android.internal.os.SamplingProfilerIntegration;
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
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700218 // The lock of mProviderMap protects the following variables.
219 final HashMap<String, ProviderClientRecord> mProviderMap
220 = new HashMap<String, ProviderClientRecord>();
221 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
222 = new HashMap<IBinder, ProviderRefCount>();
223 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
224 = new HashMap<IBinder, ProviderClientRecord>();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700225 final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
226 = new HashMap<ComponentName, ProviderClientRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227
Jeff Hamilton52d32032011-01-08 15:31:26 -0600228 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
229 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
230
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700231 final GcIdler mGcIdler = new GcIdler();
232 boolean mGcIdlerScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800233
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700234 static Handler sMainThreadHandler; // set once in main()
235
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800236 Bundle mCoreSettings = null;
237
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400238 static final class ActivityClientRecord {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800239 IBinder token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700240 int ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 Intent intent;
242 Bundle state;
243 Activity activity;
244 Window window;
245 Activity parent;
246 String embeddedID;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -0700247 Activity.NonConfigurationInstances lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248 boolean paused;
249 boolean stopped;
250 boolean hideForNow;
251 Configuration newConfig;
Dianne Hackborne88846e2009-09-30 21:34:25 -0700252 Configuration createdConfig;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700253 ActivityClientRecord nextIdle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700255 String profileFile;
256 ParcelFileDescriptor profileFd;
257 boolean autoStopProfiler;
258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 ActivityInfo activityInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400260 CompatibilityInfo compatInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700261 LoadedApk packageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262
263 List<ResultInfo> pendingResults;
264 List<Intent> pendingIntents;
265
266 boolean startsNotResumed;
267 boolean isForward;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800268 int pendingConfigChanges;
269 boolean onlyLocalRequest;
270
271 View mPendingRemoveWindow;
272 WindowManager mPendingRemoveWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800273
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700274 ActivityClientRecord() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 parent = null;
276 embeddedID = null;
277 paused = false;
278 stopped = false;
279 hideForNow = false;
280 nextIdle = null;
281 }
282
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800283 public boolean isPreHoneycomb() {
284 if (activity != null) {
285 return activity.getApplicationInfo().targetSdkVersion
286 < android.os.Build.VERSION_CODES.HONEYCOMB;
287 }
288 return false;
289 }
290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 public String toString() {
Dianne Hackbornb61a0262012-05-14 17:19:18 -0700292 ComponentName componentName = intent != null ? intent.getComponent() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800293 return "ActivityRecord{"
294 + Integer.toHexString(System.identityHashCode(this))
295 + " token=" + token + " " + (componentName == null
296 ? "no component name" : componentName.toShortString())
297 + "}";
298 }
299 }
300
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700301 final class ProviderClientRecord {
302 final String[] mNames;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 final IContentProvider mProvider;
304 final ContentProvider mLocalProvider;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700305 final IActivityManager.ContentProviderHolder mHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800306
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700307 ProviderClientRecord(String[] names, IContentProvider provider,
308 ContentProvider localProvider,
309 IActivityManager.ContentProviderHolder holder) {
310 mNames = names;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 mProvider = provider;
312 mLocalProvider = localProvider;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700313 mHolder = holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 }
315 }
316
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400317 static final class NewIntentData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318 List<Intent> intents;
319 IBinder token;
320 public String toString() {
321 return "NewIntentData{intents=" + intents + " token=" + token + "}";
322 }
323 }
324
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400325 static final class ReceiverData extends BroadcastReceiver.PendingResult {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700326 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700327 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
328 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
329 token, sendingUser);
Dianne Hackborne829fef2010-10-26 17:44:01 -0700330 this.intent = intent;
331 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700332
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 Intent intent;
334 ActivityInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400335 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800336 public String toString() {
337 return "ReceiverData{intent=" + intent + " packageName=" +
Dianne Hackborne829fef2010-10-26 17:44:01 -0700338 info.packageName + " resultCode=" + getResultCode()
339 + " resultData=" + getResultData() + " resultExtras="
340 + getResultExtras(false) + "}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 }
342 }
343
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400344 static final class CreateBackupAgentData {
Christopher Tate181fafa2009-05-14 11:12:14 -0700345 ApplicationInfo appInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400346 CompatibilityInfo compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700347 int backupMode;
348 public String toString() {
349 return "CreateBackupAgentData{appInfo=" + appInfo
350 + " backupAgent=" + appInfo.backupAgentName
351 + " mode=" + backupMode + "}";
352 }
353 }
Bob Leee5408332009-09-04 18:31:17 -0700354
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400355 static final class CreateServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800356 IBinder token;
357 ServiceInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400358 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 Intent intent;
360 public String toString() {
361 return "CreateServiceData{token=" + token + " className="
362 + info.name + " packageName=" + info.packageName
363 + " intent=" + intent + "}";
364 }
365 }
366
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400367 static final class BindServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 IBinder token;
369 Intent intent;
370 boolean rebind;
371 public String toString() {
372 return "BindServiceData{token=" + token + " intent=" + intent + "}";
373 }
374 }
375
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400376 static final class ServiceArgsData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 IBinder token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700378 boolean taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800379 int startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700380 int flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 Intent args;
382 public String toString() {
383 return "ServiceArgsData{token=" + token + " startId=" + startId
384 + " args=" + args + "}";
385 }
386 }
387
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400388 static final class AppBindData {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700389 LoadedApk info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800390 String processName;
391 ApplicationInfo appInfo;
392 List<ProviderInfo> providers;
393 ComponentName instrumentationName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 Bundle instrumentationArgs;
395 IInstrumentationWatcher instrumentationWatcher;
396 int debugMode;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800397 boolean enableOpenGlTrace;
Christopher Tate181fafa2009-05-14 11:12:14 -0700398 boolean restrictedBackupMode;
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700399 boolean persistent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800400 Configuration config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400401 CompatibilityInfo compatInfo;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700402
403 /** Initial values for {@link Profiler}. */
404 String initProfileFile;
405 ParcelFileDescriptor initProfileFd;
406 boolean initAutoStopProfiler;
407
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800408 public String toString() {
409 return "AppBindData{appInfo=" + appInfo + "}";
410 }
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700411 }
412
413 static final class Profiler {
414 String profileFile;
415 ParcelFileDescriptor profileFd;
416 boolean autoStopProfiler;
417 boolean profiling;
418 boolean handlingProfiling;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700419 public void setProfiler(String file, ParcelFileDescriptor fd) {
420 if (profiling) {
421 if (fd != null) {
422 try {
423 fd.close();
424 } catch (IOException e) {
Romain Guya998dff2012-03-23 18:58:36 -0700425 // Ignore
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700426 }
427 }
428 return;
429 }
430 if (profileFd != null) {
431 try {
432 profileFd.close();
433 } catch (IOException e) {
Romain Guya998dff2012-03-23 18:58:36 -0700434 // Ignore
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700435 }
436 }
437 profileFile = file;
438 profileFd = fd;
439 }
440 public void startProfiling() {
441 if (profileFd == null || profiling) {
442 return;
443 }
444 try {
445 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
446 8 * 1024 * 1024, 0);
447 profiling = true;
448 } catch (RuntimeException e) {
449 Slog.w(TAG, "Profiling failed on path " + profileFile);
450 try {
451 profileFd.close();
452 profileFd = null;
453 } catch (IOException e2) {
454 Slog.w(TAG, "Failure closing profile fd", e2);
455 }
456 }
457 }
458 public void stopProfiling() {
459 if (profiling) {
460 profiling = false;
461 Debug.stopMethodTracing();
462 if (profileFd != null) {
463 try {
464 profileFd.close();
465 } catch (IOException e) {
466 }
467 }
468 profileFd = null;
469 profileFile = null;
470 }
471 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 }
473
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400474 static final class DumpComponentInfo {
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700475 ParcelFileDescriptor fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700476 IBinder token;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800477 String prefix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800478 String[] args;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 }
480
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400481 static final class ResultData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800482 IBinder token;
483 List<ResultInfo> results;
484 public String toString() {
485 return "ResultData{token=" + token + " results" + results + "}";
486 }
487 }
488
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400489 static final class ContextCleanupInfo {
Dianne Hackborn21556372010-02-04 16:34:40 -0800490 ContextImpl context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800491 String what;
492 String who;
493 }
494
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400495 static final class ProfilerControlData {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700496 String path;
497 ParcelFileDescriptor fd;
498 }
499
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400500 static final class DumpHeapData {
Andy McFadden824c5102010-07-09 16:26:57 -0700501 String path;
502 ParcelFileDescriptor fd;
503 }
504
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400505 static final class UpdateCompatibilityData {
506 String pkg;
507 CompatibilityInfo info;
508 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -0700509
Romain Guy65b345f2011-07-27 18:51:50 -0700510 private native void dumpGraphicsInfo(FileDescriptor fd);
Chet Haase9c1e23b2011-03-24 10:51:31 -0700511
Romain Guy65b345f2011-07-27 18:51:50 -0700512 private class ApplicationThread extends ApplicationThreadNative {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700513 private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
514 private static final String ONE_COUNT_COLUMN = "%21s %8d";
515 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
Vasu Nori3c7131f2010-09-21 14:36:57 -0700516 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
Bob Leee5408332009-09-04 18:31:17 -0700517
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800518 // Formatting for checkin service - update version if row format changes
519 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
Bob Leee5408332009-09-04 18:31:17 -0700520
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700521 private void updatePendingConfiguration(Configuration config) {
522 synchronized (mPackages) {
523 if (mPendingConfiguration == null ||
524 mPendingConfiguration.isOtherSeqNewer(config)) {
525 mPendingConfiguration = config;
526 }
527 }
528 }
529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 public final void schedulePauseActivity(IBinder token, boolean finished,
531 boolean userLeaving, int configChanges) {
532 queueOrSendMessage(
533 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
534 token,
535 (userLeaving ? 1 : 0),
536 configChanges);
537 }
538
539 public final void scheduleStopActivity(IBinder token, boolean showWindow,
540 int configChanges) {
541 queueOrSendMessage(
542 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
543 token, 0, configChanges);
544 }
545
546 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
547 queueOrSendMessage(
548 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
549 token);
550 }
551
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800552 public final void scheduleSleeping(IBinder token, boolean sleeping) {
553 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
554 }
555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
557 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
558 }
559
560 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
561 ResultData res = new ResultData();
562 res.token = token;
563 res.results = results;
564 queueOrSendMessage(H.SEND_RESULT, res);
565 }
566
567 // we use token to identify this activity without having to send the
568 // activity itself back to the activity manager. (matters more with ipc)
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700569 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700570 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
571 Bundle state, List<ResultInfo> pendingResults,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700572 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
573 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700574 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575
576 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700577 r.ident = ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 r.intent = intent;
579 r.activityInfo = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400580 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 r.state = state;
582
583 r.pendingResults = pendingResults;
584 r.pendingIntents = pendingNewIntents;
585
586 r.startsNotResumed = notResumed;
587 r.isForward = isForward;
588
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700589 r.profileFile = profileName;
590 r.profileFd = profileFd;
591 r.autoStopProfiler = autoStopProfiler;
592
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700593 updatePendingConfiguration(curConfig);
594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800595 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
596 }
597
598 public final void scheduleRelaunchActivity(IBinder token,
599 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
Dianne Hackborn871ecdc2009-12-11 15:24:33 -0800600 int configChanges, boolean notResumed, Configuration config) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800601 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
602 configChanges, notResumed, config, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 }
604
605 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
606 NewIntentData data = new NewIntentData();
607 data.intents = intents;
608 data.token = token;
609
610 queueOrSendMessage(H.NEW_INTENT, data);
611 }
612
613 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
614 int configChanges) {
615 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
616 configChanges);
617 }
618
619 public final void scheduleReceiver(Intent intent, ActivityInfo info,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400620 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700621 boolean sync, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700622 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700623 sync, false, mAppThread.asBinder(), sendingUser);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 r.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400625 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 queueOrSendMessage(H.RECEIVER, r);
627 }
628
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400629 public final void scheduleCreateBackupAgent(ApplicationInfo app,
630 CompatibilityInfo compatInfo, int backupMode) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700631 CreateBackupAgentData d = new CreateBackupAgentData();
632 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400633 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700634 d.backupMode = backupMode;
635
636 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
637 }
638
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400639 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
640 CompatibilityInfo compatInfo) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700641 CreateBackupAgentData d = new CreateBackupAgentData();
642 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400643 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700644
645 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
646 }
647
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 public final void scheduleCreateService(IBinder token,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400649 ServiceInfo info, CompatibilityInfo compatInfo) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 CreateServiceData s = new CreateServiceData();
651 s.token = token;
652 s.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400653 s.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654
655 queueOrSendMessage(H.CREATE_SERVICE, s);
656 }
657
658 public final void scheduleBindService(IBinder token, Intent intent,
659 boolean rebind) {
660 BindServiceData s = new BindServiceData();
661 s.token = token;
662 s.intent = intent;
663 s.rebind = rebind;
664
Amith Yamasani742a6712011-05-04 14:49:28 -0700665 if (DEBUG_SERVICE)
666 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
667 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 queueOrSendMessage(H.BIND_SERVICE, s);
669 }
670
671 public final void scheduleUnbindService(IBinder token, Intent intent) {
672 BindServiceData s = new BindServiceData();
673 s.token = token;
674 s.intent = intent;
675
676 queueOrSendMessage(H.UNBIND_SERVICE, s);
677 }
678
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700679 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700680 int flags ,Intent args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800681 ServiceArgsData s = new ServiceArgsData();
682 s.token = token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700683 s.taskRemoved = taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 s.startId = startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700685 s.flags = flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 s.args = args;
687
688 queueOrSendMessage(H.SERVICE_ARGS, s);
689 }
690
691 public final void scheduleStopService(IBinder token) {
692 queueOrSendMessage(H.STOP_SERVICE, token);
693 }
694
695 public final void bindApplication(String processName,
696 ApplicationInfo appInfo, List<ProviderInfo> providers,
697 ComponentName instrumentationName, String profileFile,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700698 ParcelFileDescriptor profileFd, boolean autoStopProfiler,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800699 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
Siva Velusamy92a8b222012-03-09 16:24:04 -0800700 int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,
701 boolean persistent, Configuration config, CompatibilityInfo compatInfo,
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700702 Map<String, IBinder> services, Bundle coreSettings) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800703
704 if (services != null) {
705 // Setup the service cache in the ServiceManager
706 ServiceManager.initServiceCache(services);
707 }
708
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800709 setCoreSettings(coreSettings);
710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800711 AppBindData data = new AppBindData();
712 data.processName = processName;
713 data.appInfo = appInfo;
714 data.providers = providers;
715 data.instrumentationName = instrumentationName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800716 data.instrumentationArgs = instrumentationArgs;
717 data.instrumentationWatcher = instrumentationWatcher;
718 data.debugMode = debugMode;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800719 data.enableOpenGlTrace = enableOpenGlTrace;
Christopher Tate181fafa2009-05-14 11:12:14 -0700720 data.restrictedBackupMode = isRestrictedBackupMode;
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700721 data.persistent = persistent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800722 data.config = config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400723 data.compatInfo = compatInfo;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700724 data.initProfileFile = profileFile;
725 data.initProfileFd = profileFd;
726 data.initAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 queueOrSendMessage(H.BIND_APPLICATION, data);
728 }
729
730 public final void scheduleExit() {
731 queueOrSendMessage(H.EXIT_APPLICATION, null);
732 }
733
Christopher Tate5e1ab332009-09-01 20:32:49 -0700734 public final void scheduleSuicide() {
735 queueOrSendMessage(H.SUICIDE, null);
736 }
737
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800738 public void requestThumbnail(IBinder token) {
739 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
740 }
741
742 public void scheduleConfigurationChanged(Configuration config) {
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700743 updatePendingConfiguration(config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
745 }
746
747 public void updateTimeZone() {
748 TimeZone.setDefault(null);
749 }
750
Robert Greenwalt03595d02010-11-02 14:08:23 -0700751 public void clearDnsCache() {
752 // a non-standard API to get this to libcore
753 InetAddress.clearDnsCache();
754 }
755
Robert Greenwalt434203a2010-10-11 16:00:27 -0700756 public void setHttpProxy(String host, String port, String exclList) {
757 Proxy.setHttpProxySystemProperty(host, port, exclList);
758 }
759
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800760 public void processInBackground() {
761 mH.removeMessages(H.GC_WHEN_IDLE);
762 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
763 }
764
765 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700766 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700767 try {
768 data.fd = ParcelFileDescriptor.dup(fd);
769 data.token = servicetoken;
770 data.args = args;
771 queueOrSendMessage(H.DUMP_SERVICE, data);
772 } catch (IOException e) {
773 Slog.w(TAG, "dumpService failed", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 }
775 }
776
777 // This function exists to make sure all receiver dispatching is
778 // correctly ordered, since these are one-way calls and the binder driver
779 // applies transaction ordering per object for such calls.
780 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
Dianne Hackborn68d881c2009-10-05 13:58:17 -0700781 int resultCode, String dataStr, Bundle extras, boolean ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700782 boolean sticky, int sendingUser) throws RemoteException {
783 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
784 sticky, sendingUser);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800785 }
Bob Leee5408332009-09-04 18:31:17 -0700786
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800787 public void scheduleLowMemory() {
788 queueOrSendMessage(H.LOW_MEMORY, null);
789 }
790
791 public void scheduleActivityConfigurationChanged(IBinder token) {
792 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
793 }
794
Romain Guy7eabe552011-07-21 14:56:34 -0700795 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
796 int profileType) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700797 ProfilerControlData pcd = new ProfilerControlData();
798 pcd.path = path;
799 pcd.fd = fd;
Romain Guy7eabe552011-07-21 14:56:34 -0700800 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800801 }
802
Andy McFadden824c5102010-07-09 16:26:57 -0700803 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
804 DumpHeapData dhd = new DumpHeapData();
805 dhd.path = path;
806 dhd.fd = fd;
807 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
808 }
809
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700810 public void setSchedulingGroup(int group) {
811 // Note: do this immediately, since going into the foreground
812 // should happen regardless of what pending work we have to do
813 // and the activity manager will wait for us to report back that
814 // we are done before sending us to the background.
815 try {
816 Process.setProcessGroup(Process.myPid(), group);
817 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800818 Slog.w(TAG, "Failed setting process group to " + group, e);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700819 }
820 }
Bob Leee5408332009-09-04 18:31:17 -0700821
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700822 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
823 Debug.getMemoryInfo(outInfo);
824 }
Bob Leee5408332009-09-04 18:31:17 -0700825
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700826 public void dispatchPackageBroadcast(int cmd, String[] packages) {
827 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
828 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700829
830 public void scheduleCrash(String msg) {
831 queueOrSendMessage(H.SCHEDULE_CRASH, msg);
832 }
Dianne Hackborn625ac272010-09-17 18:29:22 -0700833
Dianne Hackborn30d71892010-12-11 10:37:55 -0800834 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
835 String prefix, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700836 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700837 try {
838 data.fd = ParcelFileDescriptor.dup(fd);
839 data.token = activitytoken;
840 data.prefix = prefix;
841 data.args = args;
842 queueOrSendMessage(H.DUMP_ACTIVITY, data);
843 } catch (IOException e) {
844 Slog.w(TAG, "dumpActivity failed", e);
Dianne Hackborn625ac272010-09-17 18:29:22 -0700845 }
846 }
Chet Haase9c1e23b2011-03-24 10:51:31 -0700847
Marco Nelissen18cb2872011-11-15 11:19:53 -0800848 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
849 String[] args) {
850 DumpComponentInfo data = new DumpComponentInfo();
851 try {
852 data.fd = ParcelFileDescriptor.dup(fd);
853 data.token = providertoken;
854 data.args = args;
855 queueOrSendMessage(H.DUMP_PROVIDER, data);
856 } catch (IOException e) {
857 Slog.w(TAG, "dumpProvider failed", e);
858 }
859 }
860
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 @Override
Dianne Hackbornb437e092011-08-05 17:50:29 -0700862 public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
863 boolean all, String[] args) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700864 FileOutputStream fout = new FileOutputStream(fd);
865 PrintWriter pw = new PrintWriter(fout);
866 try {
Romain Guya998dff2012-03-23 18:58:36 -0700867 return dumpMemInfo(pw, checkin, all);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700868 } finally {
Chet Haase9c1e23b2011-03-24 10:51:31 -0700869 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -0700870 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700871 }
872
Romain Guya998dff2012-03-23 18:58:36 -0700873 private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800874 long nativeMax = Debug.getNativeHeapSize() / 1024;
875 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
876 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
877
878 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
879 Debug.getMemoryInfo(memInfo);
880
Dianne Hackbornb437e092011-08-05 17:50:29 -0700881 if (!all) {
882 return memInfo;
883 }
884
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800885 Runtime runtime = Runtime.getRuntime();
886
887 long dalvikMax = runtime.totalMemory() / 1024;
888 long dalvikFree = runtime.freeMemory() / 1024;
889 long dalvikAllocated = dalvikMax - dalvikFree;
890 long viewInstanceCount = ViewDebug.getViewInstanceCount();
Romain Guy65b345f2011-07-27 18:51:50 -0700891 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
Brian Carlstromc21550a2010-10-05 21:34:06 -0700892 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
893 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800894 int globalAssetCount = AssetManager.getGlobalAssetCount();
895 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
896 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
897 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
898 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
Brian Carlstromc9d5b312010-10-05 22:23:41 -0700899 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
Vasu Noric3849202010-03-09 10:47:25 -0800900 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
Bob Leee5408332009-09-04 18:31:17 -0700901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 // For checkin, we print one long comma-separated list of values
Dianne Hackbornb437e092011-08-05 17:50:29 -0700903 if (checkin) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800904 // NOTE: if you change anything significant below, also consider changing
905 // ACTIVITY_THREAD_CHECKIN_VERSION.
Bob Leee5408332009-09-04 18:31:17 -0700906 String processName = (mBoundApplication != null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 ? mBoundApplication.processName : "unknown";
Bob Leee5408332009-09-04 18:31:17 -0700908
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800909 // Header
910 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
911 pw.print(Process.myPid()); pw.print(',');
912 pw.print(processName); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700913
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 // Heap info - max
915 pw.print(nativeMax); pw.print(',');
916 pw.print(dalvikMax); pw.print(',');
917 pw.print("N/A,");
918 pw.print(nativeMax + dalvikMax); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700919
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 // Heap info - allocated
921 pw.print(nativeAllocated); pw.print(',');
922 pw.print(dalvikAllocated); pw.print(',');
923 pw.print("N/A,");
924 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 // Heap info - free
927 pw.print(nativeFree); pw.print(',');
928 pw.print(dalvikFree); pw.print(',');
929 pw.print("N/A,");
930 pw.print(nativeFree + dalvikFree); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700931
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 // Heap info - proportional set size
933 pw.print(memInfo.nativePss); pw.print(',');
934 pw.print(memInfo.dalvikPss); pw.print(',');
935 pw.print(memInfo.otherPss); pw.print(',');
936 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700937
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800938 // Heap info - shared
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700939 pw.print(memInfo.nativeSharedDirty); pw.print(',');
940 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
941 pw.print(memInfo.otherSharedDirty); pw.print(',');
942 pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
943 + memInfo.otherSharedDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700944
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 // Heap info - private
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700946 pw.print(memInfo.nativePrivateDirty); pw.print(',');
947 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
948 pw.print(memInfo.otherPrivateDirty); pw.print(',');
949 pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
950 + memInfo.otherPrivateDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 // Object counts
953 pw.print(viewInstanceCount); pw.print(',');
954 pw.print(viewRootInstanceCount); pw.print(',');
955 pw.print(appContextInstanceCount); pw.print(',');
956 pw.print(activityInstanceCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 pw.print(globalAssetCount); pw.print(',');
959 pw.print(globalAssetManagerCount); pw.print(',');
960 pw.print(binderLocalObjectCount); pw.print(',');
961 pw.print(binderProxyObjectCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700962
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 pw.print(binderDeathObjectCount); pw.print(',');
964 pw.print(openSslSocketCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700965
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 // SQL
Vasu Noric3849202010-03-09 10:47:25 -0800967 pw.print(stats.memoryUsed / 1024); pw.print(',');
Jeff Brown2a293b62012-01-19 14:02:22 -0800968 pw.print(stats.memoryUsed / 1024); pw.print(',');
969 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
Dianne Hackbornb437e092011-08-05 17:50:29 -0700970 pw.print(stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -0800971 for (int i = 0; i < stats.dbStats.size(); i++) {
972 DbStats dbStats = stats.dbStats.get(i);
Dianne Hackbornb437e092011-08-05 17:50:29 -0700973 pw.print(','); pw.print(dbStats.dbName);
974 pw.print(','); pw.print(dbStats.pageSize);
975 pw.print(','); pw.print(dbStats.dbSize);
976 pw.print(','); pw.print(dbStats.lookaside);
977 pw.print(','); pw.print(dbStats.cache);
978 pw.print(','); pw.print(dbStats.cache);
Vasu Noric3849202010-03-09 10:47:25 -0800979 }
Dianne Hackbornb437e092011-08-05 17:50:29 -0700980 pw.println();
Bob Leee5408332009-09-04 18:31:17 -0700981
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700982 return memInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800983 }
Bob Leee5408332009-09-04 18:31:17 -0700984
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 // otherwise, show human-readable format
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700986 printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
987 printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
988 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
989 "------");
990 printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
991 memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
992 printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
993 memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800994
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700995 int otherPss = memInfo.otherPss;
996 int otherSharedDirty = memInfo.otherSharedDirty;
997 int otherPrivateDirty = memInfo.otherPrivateDirty;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700999 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
Romain Guy65b345f2011-07-27 18:51:50 -07001000 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001001 memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
1002 memInfo.getOtherPrivateDirty(i), "", "", "");
1003 otherPss -= memInfo.getOtherPss(i);
1004 otherSharedDirty -= memInfo.getOtherSharedDirty(i);
1005 otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
1006 }
1007
1008 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
1009 otherPrivateDirty, "", "", "");
1010 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
1011 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
1012 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
1013 nativeFree+dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014
1015 pw.println(" ");
1016 pw.println(" Objects");
Romain Guy65b345f2011-07-27 18:51:50 -07001017 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001018 viewRootInstanceCount);
1019
1020 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1021 "Activities:", activityInstanceCount);
1022
1023 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1024 "AssetManagers:", globalAssetManagerCount);
1025
1026 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1027 "Proxy Binders:", binderProxyObjectCount);
1028 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
1029
1030 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
Bob Leee5408332009-09-04 18:31:17 -07001031
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001032 // SQLite mem info
1033 pw.println(" ");
1034 pw.println(" SQL");
Jeff Brown2a293b62012-01-19 14:02:22 -08001035 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1036 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1037 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -08001038 pw.println(" ");
1039 int N = stats.dbStats.size();
1040 if (N > 0) {
1041 pw.println(" DATABASES");
Vasu Nori3c7131f2010-09-21 14:36:57 -07001042 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1043 "Dbname");
Vasu Noric3849202010-03-09 10:47:25 -08001044 for (int i = 0; i < N; i++) {
1045 DbStats dbStats = stats.dbStats.get(i);
Vasu Nori3c7131f2010-09-21 14:36:57 -07001046 printRow(pw, DB_INFO_FORMAT,
1047 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1048 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1049 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1050 dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -08001051 }
1052 }
Bob Leee5408332009-09-04 18:31:17 -07001053
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001054 // Asset details.
1055 String assetAlloc = AssetManager.getAssetAllocations();
1056 if (assetAlloc != null) {
1057 pw.println(" ");
1058 pw.println(" Asset Allocations");
1059 pw.print(assetAlloc);
1060 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001061
1062 return memInfo;
1063 }
1064
1065 @Override
1066 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1067 dumpGraphicsInfo(fd);
Jeff Brown98365d72012-08-19 20:30:52 -07001068 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 }
1070
Jeff Brown6754ba22011-12-14 20:20:01 -08001071 @Override
1072 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1073 PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
1074 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1075 SQLiteDebug.dump(printer, args);
1076 pw.flush();
1077 }
1078
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001079 @Override
1080 public void unstableProviderDied(IBinder provider) {
1081 queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1082 }
1083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 private void printRow(PrintWriter pw, String format, Object...objs) {
1085 pw.println(String.format(format, objs));
1086 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001087
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08001088 public void setCoreSettings(Bundle coreSettings) {
1089 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001090 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001091
1092 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1093 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1094 ucd.pkg = pkg;
1095 ucd.info = info;
1096 queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1097 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001098
1099 public void scheduleTrimMemory(int level) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001100 queueOrSendMessage(H.TRIM_MEMORY, null, level);
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001101 }
Marco Nelissen18cb2872011-11-15 11:19:53 -08001102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001103 }
1104
Romain Guy65b345f2011-07-27 18:51:50 -07001105 private class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001106 public static final int LAUNCH_ACTIVITY = 100;
1107 public static final int PAUSE_ACTIVITY = 101;
1108 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1109 public static final int STOP_ACTIVITY_SHOW = 103;
1110 public static final int STOP_ACTIVITY_HIDE = 104;
1111 public static final int SHOW_WINDOW = 105;
1112 public static final int HIDE_WINDOW = 106;
1113 public static final int RESUME_ACTIVITY = 107;
1114 public static final int SEND_RESULT = 108;
Brian Carlstromed7e0072011-03-24 13:27:57 -07001115 public static final int DESTROY_ACTIVITY = 109;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001116 public static final int BIND_APPLICATION = 110;
1117 public static final int EXIT_APPLICATION = 111;
1118 public static final int NEW_INTENT = 112;
1119 public static final int RECEIVER = 113;
1120 public static final int CREATE_SERVICE = 114;
1121 public static final int SERVICE_ARGS = 115;
1122 public static final int STOP_SERVICE = 116;
1123 public static final int REQUEST_THUMBNAIL = 117;
1124 public static final int CONFIGURATION_CHANGED = 118;
1125 public static final int CLEAN_UP_CONTEXT = 119;
1126 public static final int GC_WHEN_IDLE = 120;
1127 public static final int BIND_SERVICE = 121;
1128 public static final int UNBIND_SERVICE = 122;
1129 public static final int DUMP_SERVICE = 123;
1130 public static final int LOW_MEMORY = 124;
1131 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1132 public static final int RELAUNCH_ACTIVITY = 126;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001133 public static final int PROFILER_CONTROL = 127;
Christopher Tate181fafa2009-05-14 11:12:14 -07001134 public static final int CREATE_BACKUP_AGENT = 128;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001135 public static final int DESTROY_BACKUP_AGENT = 129;
1136 public static final int SUICIDE = 130;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001137 public static final int REMOVE_PROVIDER = 131;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001138 public static final int ENABLE_JIT = 132;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001139 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001140 public static final int SCHEDULE_CRASH = 134;
Andy McFadden824c5102010-07-09 16:26:57 -07001141 public static final int DUMP_HEAP = 135;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001142 public static final int DUMP_ACTIVITY = 136;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001143 public static final int SLEEPING = 137;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001144 public static final int SET_CORE_SETTINGS = 138;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001145 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001146 public static final int TRIM_MEMORY = 140;
Marco Nelissen18cb2872011-11-15 11:19:53 -08001147 public static final int DUMP_PROVIDER = 141;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001148 public static final int UNSTABLE_PROVIDER_DIED = 142;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 String codeToString(int code) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001150 if (DEBUG_MESSAGES) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001151 switch (code) {
1152 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1153 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1154 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1155 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1156 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1157 case SHOW_WINDOW: return "SHOW_WINDOW";
1158 case HIDE_WINDOW: return "HIDE_WINDOW";
1159 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1160 case SEND_RESULT: return "SEND_RESULT";
1161 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1162 case BIND_APPLICATION: return "BIND_APPLICATION";
1163 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1164 case NEW_INTENT: return "NEW_INTENT";
1165 case RECEIVER: return "RECEIVER";
1166 case CREATE_SERVICE: return "CREATE_SERVICE";
1167 case SERVICE_ARGS: return "SERVICE_ARGS";
1168 case STOP_SERVICE: return "STOP_SERVICE";
1169 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
1170 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1171 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1172 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1173 case BIND_SERVICE: return "BIND_SERVICE";
1174 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1175 case DUMP_SERVICE: return "DUMP_SERVICE";
1176 case LOW_MEMORY: return "LOW_MEMORY";
1177 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1178 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001179 case PROFILER_CONTROL: return "PROFILER_CONTROL";
Christopher Tate181fafa2009-05-14 11:12:14 -07001180 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1181 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
Christopher Tate5e1ab332009-09-01 20:32:49 -07001182 case SUICIDE: return "SUICIDE";
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001183 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001184 case ENABLE_JIT: return "ENABLE_JIT";
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001185 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001186 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
Andy McFadden824c5102010-07-09 16:26:57 -07001187 case DUMP_HEAP: return "DUMP_HEAP";
Dianne Hackborn625ac272010-09-17 18:29:22 -07001188 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001189 case SLEEPING: return "SLEEPING";
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001190 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001191 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001192 case TRIM_MEMORY: return "TRIM_MEMORY";
Marco Nelissen18cb2872011-11-15 11:19:53 -08001193 case DUMP_PROVIDER: return "DUMP_PROVIDER";
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001194 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 }
1196 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001197 return Integer.toString(code);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001198 }
1199 public void handleMessage(Message msg) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001200 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201 switch (msg.what) {
1202 case LAUNCH_ACTIVITY: {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001203 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001204 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001205
1206 r.packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001207 r.activityInfo.applicationInfo, r.compatInfo);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001208 handleLaunchActivity(r, null);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001209 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001210 } break;
1211 case RELAUNCH_ACTIVITY: {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001212 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001213 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08001214 handleRelaunchActivity(r);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001215 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001216 } break;
1217 case PAUSE_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001218 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001219 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
Bob Leee5408332009-09-04 18:31:17 -07001220 maybeSnapshot();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001221 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 break;
1223 case PAUSE_ACTIVITY_FINISHING:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001224 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001226 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 break;
1228 case STOP_ACTIVITY_SHOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001229 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001231 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 break;
1233 case STOP_ACTIVITY_HIDE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001234 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001236 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001237 break;
1238 case SHOW_WINDOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001239 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001240 handleWindowVisibility((IBinder)msg.obj, true);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001241 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001242 break;
1243 case HIDE_WINDOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001244 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 handleWindowVisibility((IBinder)msg.obj, false);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001246 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001247 break;
1248 case RESUME_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001249 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001250 handleResumeActivity((IBinder)msg.obj, true,
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001251 msg.arg1 != 0, true);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001252 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001253 break;
1254 case SEND_RESULT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001255 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 handleSendResult((ResultData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001257 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001258 break;
1259 case DESTROY_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001260 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1262 msg.arg2, false);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001263 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 break;
1265 case BIND_APPLICATION:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001266 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 AppBindData data = (AppBindData)msg.obj;
1268 handleBindApplication(data);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001269 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001270 break;
1271 case EXIT_APPLICATION:
1272 if (mInitialApplication != null) {
1273 mInitialApplication.onTerminate();
1274 }
1275 Looper.myLooper().quit();
1276 break;
1277 case NEW_INTENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001278 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 handleNewIntent((NewIntentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001280 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 break;
1282 case RECEIVER:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001283 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 handleReceiver((ReceiverData)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001285 maybeSnapshot();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001286 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 break;
1288 case CREATE_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001289 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 handleCreateService((CreateServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001291 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292 break;
1293 case BIND_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001294 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 handleBindService((BindServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001296 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 break;
1298 case UNBIND_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001299 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 handleUnbindService((BindServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001301 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 break;
1303 case SERVICE_ARGS:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001304 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 handleServiceArgs((ServiceArgsData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001306 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 break;
1308 case STOP_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001309 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 handleStopService((IBinder)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001311 maybeSnapshot();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001312 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 break;
1314 case REQUEST_THUMBNAIL:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001315 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 handleRequestThumbnail((IBinder)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001317 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 break;
1319 case CONFIGURATION_CHANGED:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001320 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001321 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001322 handleConfigurationChanged((Configuration)msg.obj, null);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001323 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 break;
1325 case CLEAN_UP_CONTEXT:
1326 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1327 cci.context.performFinalCleanup(cci.who, cci.what);
1328 break;
1329 case GC_WHEN_IDLE:
1330 scheduleGcIdler();
1331 break;
1332 case DUMP_SERVICE:
Dianne Hackborn625ac272010-09-17 18:29:22 -07001333 handleDumpService((DumpComponentInfo)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 break;
1335 case LOW_MEMORY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001336 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 handleLowMemory();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001338 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339 break;
1340 case ACTIVITY_CONFIGURATION_CHANGED:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001341 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 handleActivityConfigurationChanged((IBinder)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001343 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001344 break;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001345 case PROFILER_CONTROL:
Romain Guy7eabe552011-07-21 14:56:34 -07001346 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001347 break;
Christopher Tate181fafa2009-05-14 11:12:14 -07001348 case CREATE_BACKUP_AGENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001349 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -07001350 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001351 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate181fafa2009-05-14 11:12:14 -07001352 break;
1353 case DESTROY_BACKUP_AGENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001354 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -07001355 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001356 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate181fafa2009-05-14 11:12:14 -07001357 break;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001358 case SUICIDE:
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001359 Process.killProcess(Process.myPid());
1360 break;
1361 case REMOVE_PROVIDER:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001362 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001363 completeRemoveProvider((ProviderRefCount)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001364 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate5e1ab332009-09-01 20:32:49 -07001365 break;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001366 case ENABLE_JIT:
1367 ensureJitEnabled();
1368 break;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001369 case DISPATCH_PACKAGE_BROADCAST:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001370 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001371 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001372 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001373 break;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001374 case SCHEDULE_CRASH:
1375 throw new RemoteServiceException((String)msg.obj);
Andy McFadden824c5102010-07-09 16:26:57 -07001376 case DUMP_HEAP:
1377 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1378 break;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001379 case DUMP_ACTIVITY:
1380 handleDumpActivity((DumpComponentInfo)msg.obj);
1381 break;
Marco Nelissen18cb2872011-11-15 11:19:53 -08001382 case DUMP_PROVIDER:
1383 handleDumpProvider((DumpComponentInfo)msg.obj);
1384 break;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001385 case SLEEPING:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001386 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001387 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001388 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001389 break;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001390 case SET_CORE_SETTINGS:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001391 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001392 handleSetCoreSettings((Bundle) msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001393 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001394 break;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001395 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1396 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001397 break;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001398 case TRIM_MEMORY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001399 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001400 handleTrimMemory(msg.arg1);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001401 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001402 break;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001403 case UNSTABLE_PROVIDER_DIED:
1404 handleUnstableProviderDied((IBinder)msg.obj, false);
1405 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001406 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001407 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 }
Bob Leee5408332009-09-04 18:31:17 -07001409
Brian Carlstromed7e0072011-03-24 13:27:57 -07001410 private void maybeSnapshot() {
1411 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
Sen Hubde75702010-05-28 01:54:03 -07001412 // convert the *private* ActivityThread.PackageInfo to *public* known
1413 // android.content.pm.PackageInfo
1414 String packageName = mBoundApplication.info.mPackageName;
1415 android.content.pm.PackageInfo packageInfo = null;
1416 try {
1417 Context context = getSystemContext();
1418 if(context == null) {
1419 Log.e(TAG, "cannot get a valid context");
1420 return;
1421 }
1422 PackageManager pm = context.getPackageManager();
1423 if(pm == null) {
1424 Log.e(TAG, "cannot get a valid PackageManager");
1425 return;
1426 }
1427 packageInfo = pm.getPackageInfo(
1428 packageName, PackageManager.GET_ACTIVITIES);
1429 } catch (NameNotFoundException e) {
1430 Log.e(TAG, "cannot get package info for " + packageName, e);
1431 }
1432 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
Bob Leee5408332009-09-04 18:31:17 -07001433 }
1434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 }
1436
Romain Guy65b345f2011-07-27 18:51:50 -07001437 private class Idler implements MessageQueue.IdleHandler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 public final boolean queueIdle() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001439 ActivityClientRecord a = mNewActivities;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001440 boolean stopProfiling = false;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001441 if (mBoundApplication != null && mProfiler.profileFd != null
1442 && mProfiler.autoStopProfiler) {
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001443 stopProfiling = true;
1444 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 if (a != null) {
1446 mNewActivities = null;
1447 IActivityManager am = ActivityManagerNative.getDefault();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001448 ActivityClientRecord prev;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001449 do {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001450 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 TAG, "Reporting idle of " + a +
1452 " finished=" +
Romain Guy65b345f2011-07-27 18:51:50 -07001453 (a.activity != null && a.activity.mFinished));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001454 if (a.activity != null && !a.activity.mFinished) {
1455 try {
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001456 am.activityIdle(a.token, a.createdConfig, stopProfiling);
Dianne Hackborne88846e2009-09-30 21:34:25 -07001457 a.createdConfig = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001458 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07001459 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 }
1461 }
1462 prev = a;
1463 a = a.nextIdle;
1464 prev.nextIdle = null;
1465 } while (a != null);
1466 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001467 if (stopProfiling) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001468 mProfiler.stopProfiling();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001469 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001470 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 return false;
1472 }
1473 }
1474
1475 final class GcIdler implements MessageQueue.IdleHandler {
1476 public final boolean queueIdle() {
1477 doGcIfNeeded();
1478 return false;
1479 }
1480 }
1481
Romain Guy65b345f2011-07-27 18:51:50 -07001482 private static class ResourcesKey {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001483 final private String mResDir;
Jeff Browna492c3a2012-08-23 19:48:44 -07001484 final private int mDisplayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001485 final private Configuration mOverrideConfiguration;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001486 final private float mScale;
1487 final private int mHash;
Bob Leee5408332009-09-04 18:31:17 -07001488
Jeff Browna492c3a2012-08-23 19:48:44 -07001489 ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001490 mResDir = resDir;
Jeff Browna492c3a2012-08-23 19:48:44 -07001491 mDisplayId = displayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001492 if (overrideConfiguration != null) {
1493 if (Configuration.EMPTY.equals(overrideConfiguration)) {
1494 overrideConfiguration = null;
1495 }
1496 }
1497 mOverrideConfiguration = overrideConfiguration;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001498 mScale = scale;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001499 int hash = 17;
1500 hash = 31 * hash + mResDir.hashCode();
Jeff Browna492c3a2012-08-23 19:48:44 -07001501 hash = 31 * hash + mDisplayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001502 hash = 31 * hash + (mOverrideConfiguration != null
1503 ? mOverrideConfiguration.hashCode() : 0);
1504 hash = 31 * hash + Float.floatToIntBits(mScale);
1505 mHash = hash;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001506 }
Bob Leee5408332009-09-04 18:31:17 -07001507
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001508 @Override
1509 public int hashCode() {
1510 return mHash;
1511 }
1512
1513 @Override
1514 public boolean equals(Object obj) {
1515 if (!(obj instanceof ResourcesKey)) {
1516 return false;
1517 }
1518 ResourcesKey peer = (ResourcesKey) obj;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001519 if (!mResDir.equals(peer.mResDir)) {
1520 return false;
1521 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001522 if (mDisplayId != peer.mDisplayId) {
1523 return false;
1524 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001525 if (mOverrideConfiguration != peer.mOverrideConfiguration) {
1526 if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
1527 return false;
1528 }
1529 if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
1530 return false;
1531 }
1532 }
1533 if (mScale != peer.mScale) {
1534 return false;
1535 }
1536 return true;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001537 }
1538 }
1539
Romain Guy65b345f2011-07-27 18:51:50 -07001540 public static ActivityThread currentActivityThread() {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07001541 return sThreadLocal.get();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001542 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543
Romain Guy65b345f2011-07-27 18:51:50 -07001544 public static String currentPackageName() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001545 ActivityThread am = currentActivityThread();
1546 return (am != null && am.mBoundApplication != null)
1547 ? am.mBoundApplication.processName : null;
1548 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001549
Romain Guy65b345f2011-07-27 18:51:50 -07001550 public static Application currentApplication() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001551 ActivityThread am = currentActivityThread();
1552 return am != null ? am.mInitialApplication : null;
1553 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001554
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001555 public static IPackageManager getPackageManager() {
1556 if (sPackageManager != null) {
1557 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1558 return sPackageManager;
1559 }
1560 IBinder b = ServiceManager.getService("package");
1561 //Slog.v("PackageManager", "default service binder = " + b);
1562 sPackageManager = IPackageManager.Stub.asInterface(b);
1563 //Slog.v("PackageManager", "default service = " + sPackageManager);
1564 return sPackageManager;
1565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566
Jeff Browna492c3a2012-08-23 19:48:44 -07001567 private void flushDisplayMetricsLocked() {
1568 mDefaultDisplayMetrics.clear();
1569 }
1570
1571 DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
1572 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1573 DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
1574 if (dm != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001575 return dm;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001576 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001577 dm = new DisplayMetrics();
Jeff Brown848c2dc2012-08-19 20:18:08 -07001578
Jeff Brownbd6e1502012-08-28 03:27:37 -07001579 DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
Jeff Brown848c2dc2012-08-19 20:18:08 -07001580 if (displayManager == null) {
1581 // may be null early in system startup
Jeff Brown848c2dc2012-08-19 20:18:08 -07001582 dm.setToDefaults();
1583 return dm;
1584 }
1585
Jeff Browna492c3a2012-08-23 19:48:44 -07001586 if (isDefaultDisplay) {
1587 mDefaultDisplayMetrics.put(ci, dm);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001588 }
Jeff Brown848c2dc2012-08-19 20:18:08 -07001589
Jeff Brownd32460c2012-07-20 16:15:36 -07001590 CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
1591 cih.set(ci);
Jeff Browna492c3a2012-08-23 19:48:44 -07001592 Display d = displayManager.getCompatibleDisplay(displayId, cih);
Jeff Browna3909a92012-09-09 00:57:09 -07001593 if (d != null) {
1594 d.getMetrics(dm);
1595 } else {
1596 // Display no longer exists
1597 // FIXME: This would not be a problem if we kept the Display object around
1598 // instead of using the raw display id everywhere. The Display object caches
1599 // its information even after the display has been removed.
1600 dm.setToDefaults();
1601 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001602 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1603 // + metrics.heightPixels + " den=" + metrics.density
1604 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001605 return dm;
1606 }
1607
Romain Guy65b345f2011-07-27 18:51:50 -07001608 private Configuration mMainThreadConfig = new Configuration();
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001609 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1610 CompatibilityInfo compat) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001611 if (config == null) {
1612 return null;
1613 }
1614 if (compat != null && !compat.supportsScreen()) {
1615 mMainThreadConfig.setTo(config);
1616 config = mMainThreadConfig;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001617 compat.applyToConfiguration(displayDensity, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001618 }
1619 return config;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001622 /**
1623 * Creates the top level Resources for applications with the given compatibility info.
1624 *
1625 * @param resDir the resource directory.
1626 * @param compInfo the compability info. It will use the default compatibility info when it's
1627 * null.
1628 */
Jeff Browna492c3a2012-08-23 19:48:44 -07001629 Resources getTopLevelResources(String resDir,
1630 int displayId, Configuration overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001631 CompatibilityInfo compInfo) {
Jeff Browna492c3a2012-08-23 19:48:44 -07001632 ResourcesKey key = new ResourcesKey(resDir,
1633 displayId, overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001634 compInfo.applicationScale);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001635 Resources r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001636 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001637 // Resources is app scale dependent.
1638 if (false) {
1639 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1640 + compInfo.applicationScale);
1641 }
1642 WeakReference<Resources> wr = mActiveResources.get(key);
1643 r = wr != null ? wr.get() : null;
1644 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1645 if (r != null && r.getAssets().isUpToDate()) {
1646 if (false) {
1647 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1648 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1649 }
1650 return r;
1651 }
1652 }
1653
1654 //if (r != null) {
1655 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1656 // + r + " " + resDir);
1657 //}
1658
1659 AssetManager assets = new AssetManager();
1660 if (assets.addAssetPath(resDir) == 0) {
1661 return null;
1662 }
1663
1664 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
Jeff Browna492c3a2012-08-23 19:48:44 -07001665 DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
Dianne Hackborn756220b2012-08-14 16:45:30 -07001666 Configuration config;
Jeff Browna492c3a2012-08-23 19:48:44 -07001667 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1668 if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07001669 config = new Configuration(getConfiguration());
Jeff Browna492c3a2012-08-23 19:48:44 -07001670 if (!isDefaultDisplay) {
1671 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
1672 }
1673 if (key.mOverrideConfiguration != null) {
1674 config.updateFrom(key.mOverrideConfiguration);
1675 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001676 } else {
1677 config = getConfiguration();
1678 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001679 r = new Resources(assets, dm, config, compInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001680 if (false) {
1681 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1682 + r.getConfiguration() + " appScale="
1683 + r.getCompatibilityInfo().applicationScale);
1684 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001685
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001686 synchronized (mPackages) {
1687 WeakReference<Resources> wr = mActiveResources.get(key);
1688 Resources existing = wr != null ? wr.get() : null;
1689 if (existing != null && existing.getAssets().isUpToDate()) {
1690 // Someone else already created the resources while we were
1691 // unlocked; go ahead and use theirs.
1692 r.getAssets().close();
1693 return existing;
1694 }
1695
1696 // XXX need to remove entries when weak references go away
1697 mActiveResources.put(key, new WeakReference<Resources>(r));
1698 return r;
1699 }
1700 }
1701
1702 /**
1703 * Creates the top level resources for the given package.
1704 */
Jeff Browna492c3a2012-08-23 19:48:44 -07001705 Resources getTopLevelResources(String resDir,
1706 int displayId, Configuration overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001707 LoadedApk pkgInfo) {
Jeff Browna492c3a2012-08-23 19:48:44 -07001708 return getTopLevelResources(resDir, displayId, overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001709 pkgInfo.mCompatibilityInfo.get());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001710 }
1711
1712 final Handler getHandler() {
1713 return mH;
1714 }
1715
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001716 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1717 int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001718 synchronized (mPackages) {
1719 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001720 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1721 ref = mPackages.get(packageName);
1722 } else {
1723 ref = mResourcePackages.get(packageName);
1724 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001725 LoadedApk packageInfo = ref != null ? ref.get() : null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001726 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001727 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1728 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001729 if (packageInfo != null && (packageInfo.mResources == null
1730 || packageInfo.mResources.getAssets().isUpToDate())) {
1731 if (packageInfo.isSecurityViolation()
1732 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1733 throw new SecurityException(
1734 "Requesting code from " + packageName
1735 + " to be run in process "
1736 + mBoundApplication.processName
1737 + "/" + mBoundApplication.appInfo.uid);
1738 }
1739 return packageInfo;
1740 }
1741 }
1742
1743 ApplicationInfo ai = null;
1744 try {
1745 ai = getPackageManager().getApplicationInfo(packageName,
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001746 PackageManager.GET_SHARED_LIBRARY_FILES, UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747 } catch (RemoteException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07001748 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 }
1750
1751 if (ai != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001752 return getPackageInfo(ai, compatInfo, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001753 }
1754
1755 return null;
1756 }
1757
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001758 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1759 int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1761 boolean securityViolation = includeCode && ai.uid != 0
1762 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001763 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
Amith Yamasani742a6712011-05-04 14:49:28 -07001764 : true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001765 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1766 |Context.CONTEXT_IGNORE_SECURITY))
1767 == Context.CONTEXT_INCLUDE_CODE) {
1768 if (securityViolation) {
1769 String msg = "Requesting code from " + ai.packageName
1770 + " (with uid " + ai.uid + ")";
1771 if (mBoundApplication != null) {
1772 msg = msg + " to be run in process "
1773 + mBoundApplication.processName + " (with uid "
1774 + mBoundApplication.appInfo.uid + ")";
1775 }
1776 throw new SecurityException(msg);
1777 }
1778 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001779 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 }
1781
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001782 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1783 CompatibilityInfo compatInfo) {
1784 return getPackageInfo(ai, compatInfo, null, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001785 }
1786
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001787 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1788 synchronized (mPackages) {
1789 WeakReference<LoadedApk> ref;
1790 if (includeCode) {
1791 ref = mPackages.get(packageName);
1792 } else {
1793 ref = mResourcePackages.get(packageName);
1794 }
1795 return ref != null ? ref.get() : null;
1796 }
1797 }
1798
Romain Guy65b345f2011-07-27 18:51:50 -07001799 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1801 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001802 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001803 if (includeCode) {
1804 ref = mPackages.get(aInfo.packageName);
1805 } else {
1806 ref = mResourcePackages.get(aInfo.packageName);
1807 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001808 LoadedApk packageInfo = ref != null ? ref.get() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001809 if (packageInfo == null || (packageInfo.mResources != null
1810 && !packageInfo.mResources.getAssets().isUpToDate())) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001811 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001812 : "Loading resource-only package ") + aInfo.packageName
1813 + " (in " + (mBoundApplication != null
1814 ? mBoundApplication.processName : null)
1815 + ")");
1816 packageInfo =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001817 new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001818 securityViolation, includeCode &&
1819 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1820 if (includeCode) {
1821 mPackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001822 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001823 } else {
1824 mResourcePackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001825 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001826 }
1827 }
1828 return packageInfo;
1829 }
1830 }
1831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 ActivityThread() {
1833 }
1834
1835 public ApplicationThread getApplicationThread()
1836 {
1837 return mAppThread;
1838 }
1839
1840 public Instrumentation getInstrumentation()
1841 {
1842 return mInstrumentation;
1843 }
1844
1845 public Configuration getConfiguration() {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001846 return mResConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 }
1848
1849 public boolean isProfiling() {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001850 return mProfiler != null && mProfiler.profileFile != null
1851 && mProfiler.profileFd == null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 }
1853
1854 public String getProfileFilePath() {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001855 return mProfiler.profileFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 }
1857
1858 public Looper getLooper() {
1859 return mLooper;
1860 }
1861
1862 public Application getApplication() {
1863 return mInitialApplication;
1864 }
Bob Leee5408332009-09-04 18:31:17 -07001865
Dianne Hackbornd97c7ad2009-06-19 11:37:35 -07001866 public String getProcessName() {
1867 return mBoundApplication.processName;
1868 }
Bob Leee5408332009-09-04 18:31:17 -07001869
Dianne Hackborn21556372010-02-04 16:34:40 -08001870 public ContextImpl getSystemContext() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001871 synchronized (this) {
1872 if (mSystemContext == null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001873 ContextImpl context =
1874 ContextImpl.createSystemContext(this);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001875 LoadedApk info = new LoadedApk(this, "android", context, null,
1876 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001877 context.init(info, null, this);
1878 context.getResources().updateConfiguration(
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001879 getConfiguration(), getDisplayMetricsLocked(
Jeff Browna492c3a2012-08-23 19:48:44 -07001880 Display.DEFAULT_DISPLAY,
1881 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001882 mSystemContext = context;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001883 //Slog.i(TAG, "Created system resources " + context.getResources()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001884 // + ": " + context.getResources().getConfiguration());
1885 }
1886 }
1887 return mSystemContext;
1888 }
1889
Mike Cleron432b7132009-09-24 15:28:29 -07001890 public void installSystemApplicationInfo(ApplicationInfo info) {
1891 synchronized (this) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001892 ContextImpl context = getSystemContext();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001893 context.init(new LoadedApk(this, "android", context, info,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001894 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001895
1896 // give ourselves a default profiler
1897 mProfiler = new Profiler();
Mike Cleron432b7132009-09-24 15:28:29 -07001898 }
1899 }
1900
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001901 void ensureJitEnabled() {
1902 if (!mJitEnabled) {
1903 mJitEnabled = true;
1904 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1905 }
1906 }
1907
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 void scheduleGcIdler() {
1909 if (!mGcIdlerScheduled) {
1910 mGcIdlerScheduled = true;
1911 Looper.myQueue().addIdleHandler(mGcIdler);
1912 }
1913 mH.removeMessages(H.GC_WHEN_IDLE);
1914 }
1915
1916 void unscheduleGcIdler() {
1917 if (mGcIdlerScheduled) {
1918 mGcIdlerScheduled = false;
1919 Looper.myQueue().removeIdleHandler(mGcIdler);
1920 }
1921 mH.removeMessages(H.GC_WHEN_IDLE);
1922 }
1923
1924 void doGcIfNeeded() {
1925 mGcIdlerScheduled = false;
1926 final long now = SystemClock.uptimeMillis();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001927 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 // + "m now=" + now);
1929 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001930 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001931 BinderInternal.forceGc("bg");
1932 }
1933 }
1934
Jeff Hamilton52d32032011-01-08 15:31:26 -06001935 public void registerOnActivityPausedListener(Activity activity,
1936 OnActivityPausedListener listener) {
1937 synchronized (mOnPauseListeners) {
1938 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1939 if (list == null) {
1940 list = new ArrayList<OnActivityPausedListener>();
1941 mOnPauseListeners.put(activity, list);
1942 }
1943 list.add(listener);
1944 }
1945 }
1946
Jeff Hamiltonce3224c2011-01-17 11:05:03 -08001947 public void unregisterOnActivityPausedListener(Activity activity,
1948 OnActivityPausedListener listener) {
1949 synchronized (mOnPauseListeners) {
1950 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1951 if (list != null) {
1952 list.remove(listener);
1953 }
1954 }
1955 }
1956
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001957 public final ActivityInfo resolveActivityInfo(Intent intent) {
1958 ActivityInfo aInfo = intent.resolveActivityInfo(
1959 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
1960 if (aInfo == null) {
1961 // Throw an exception.
1962 Instrumentation.checkStartActivityResult(
Dianne Hackborna4972e92012-03-14 10:38:05 -07001963 ActivityManager.START_CLASS_NOT_FOUND, intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001964 }
1965 return aInfo;
1966 }
Bob Leee5408332009-09-04 18:31:17 -07001967
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 public final Activity startActivityNow(Activity parent, String id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001969 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001970 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001971 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001972 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001973 r.ident = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001974 r.intent = intent;
1975 r.state = state;
1976 r.parent = parent;
1977 r.embeddedID = id;
1978 r.activityInfo = activityInfo;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001979 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001980 if (localLOGV) {
1981 ComponentName compname = intent.getComponent();
1982 String name;
1983 if (compname != null) {
1984 name = compname.toShortString();
1985 } else {
1986 name = "(Intent " + intent + ").getComponent() returned null";
1987 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001988 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 + ", comp=" + name
1990 + ", token=" + token);
1991 }
Christopher Tateb70f3df2009-04-07 16:07:59 -07001992 return performLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001993 }
1994
1995 public final Activity getActivity(IBinder token) {
1996 return mActivities.get(token).activity;
1997 }
1998
1999 public final void sendActivityResult(
2000 IBinder token, String id, int requestCode,
2001 int resultCode, Intent data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002002 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
Chris Tate8a7dc172009-03-24 20:11:42 -07002003 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2005 list.add(new ResultInfo(id, requestCode, resultCode, data));
2006 mAppThread.scheduleSendResult(token, list);
2007 }
2008
2009 // if the thread hasn't started yet, we don't have the handler, so just
2010 // save the messages until we're ready.
Romain Guy65b345f2011-07-27 18:51:50 -07002011 private void queueOrSendMessage(int what, Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002012 queueOrSendMessage(what, obj, 0, 0);
2013 }
2014
Romain Guy65b345f2011-07-27 18:51:50 -07002015 private void queueOrSendMessage(int what, Object obj, int arg1) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002016 queueOrSendMessage(what, obj, arg1, 0);
2017 }
2018
Romain Guy65b345f2011-07-27 18:51:50 -07002019 private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 synchronized (this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002021 if (DEBUG_MESSAGES) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002022 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2023 + ": " + arg1 + " / " + obj);
2024 Message msg = Message.obtain();
2025 msg.what = what;
2026 msg.obj = obj;
2027 msg.arg1 = arg1;
2028 msg.arg2 = arg2;
2029 mH.sendMessage(msg);
2030 }
2031 }
2032
Dianne Hackborn21556372010-02-04 16:34:40 -08002033 final void scheduleContextCleanup(ContextImpl context, String who,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002034 String what) {
2035 ContextCleanupInfo cci = new ContextCleanupInfo();
2036 cci.context = context;
2037 cci.who = who;
2038 cci.what = what;
2039 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
2040 }
2041
Romain Guy65b345f2011-07-27 18:51:50 -07002042 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002043 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2044
2045 ActivityInfo aInfo = r.activityInfo;
2046 if (r.packageInfo == null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002047 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002048 Context.CONTEXT_INCLUDE_CODE);
2049 }
Bob Leee5408332009-09-04 18:31:17 -07002050
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051 ComponentName component = r.intent.getComponent();
2052 if (component == null) {
2053 component = r.intent.resolveActivity(
2054 mInitialApplication.getPackageManager());
2055 r.intent.setComponent(component);
2056 }
2057
2058 if (r.activityInfo.targetActivity != null) {
2059 component = new ComponentName(r.activityInfo.packageName,
2060 r.activityInfo.targetActivity);
2061 }
2062
2063 Activity activity = null;
2064 try {
2065 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2066 activity = mInstrumentation.newActivity(
2067 cl, component.getClassName(), r.intent);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002068 StrictMode.incrementExpectedActivityCount(activity.getClass());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002069 r.intent.setExtrasClassLoader(cl);
2070 if (r.state != null) {
2071 r.state.setClassLoader(cl);
2072 }
2073 } catch (Exception e) {
2074 if (!mInstrumentation.onException(activity, e)) {
2075 throw new RuntimeException(
2076 "Unable to instantiate activity " + component
2077 + ": " + e.toString(), e);
2078 }
2079 }
2080
2081 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002082 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07002083
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002084 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2085 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002086 TAG, r + ": app=" + app
2087 + ", appName=" + app.getPackageName()
2088 + ", pkg=" + r.packageInfo.getPackageName()
2089 + ", comp=" + r.intent.getComponent().toShortString()
2090 + ", dir=" + r.packageInfo.getAppDir());
2091
2092 if (activity != null) {
Jeff Brownefd43bd2012-09-21 17:02:35 -07002093 Context appContext = createBaseContextForActivity(r, activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002095 Configuration config = new Configuration(mCompatConfiguration);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002096 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002097 + r.activityInfo.name + " with config " + config);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002098 activity.attach(appContext, this, getInstrumentation(), r.token,
2099 r.ident, app, r.intent, r.activityInfo, title, r.parent,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002100 r.embeddedID, r.lastNonConfigurationInstances, config);
Bob Leee5408332009-09-04 18:31:17 -07002101
Christopher Tateb70f3df2009-04-07 16:07:59 -07002102 if (customIntent != null) {
2103 activity.mIntent = customIntent;
2104 }
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002105 r.lastNonConfigurationInstances = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002106 activity.mStartedActivity = false;
2107 int theme = r.activityInfo.getThemeResource();
2108 if (theme != 0) {
2109 activity.setTheme(theme);
2110 }
2111
2112 activity.mCalled = false;
2113 mInstrumentation.callActivityOnCreate(activity, r.state);
2114 if (!activity.mCalled) {
2115 throw new SuperNotCalledException(
2116 "Activity " + r.intent.getComponent().toShortString() +
2117 " did not call through to super.onCreate()");
2118 }
2119 r.activity = activity;
2120 r.stopped = true;
2121 if (!r.activity.mFinished) {
2122 activity.performStart();
2123 r.stopped = false;
2124 }
2125 if (!r.activity.mFinished) {
2126 if (r.state != null) {
2127 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2128 }
2129 }
2130 if (!r.activity.mFinished) {
2131 activity.mCalled = false;
2132 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2133 if (!activity.mCalled) {
2134 throw new SuperNotCalledException(
2135 "Activity " + r.intent.getComponent().toShortString() +
2136 " did not call through to super.onPostCreate()");
2137 }
2138 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002139 }
2140 r.paused = true;
2141
2142 mActivities.put(r.token, r);
2143
2144 } catch (SuperNotCalledException e) {
2145 throw e;
2146
2147 } catch (Exception e) {
2148 if (!mInstrumentation.onException(activity, e)) {
2149 throw new RuntimeException(
2150 "Unable to start activity " + component
2151 + ": " + e.toString(), e);
2152 }
2153 }
2154
2155 return activity;
2156 }
2157
Jeff Brownefd43bd2012-09-21 17:02:35 -07002158 private Context createBaseContextForActivity(ActivityClientRecord r,
2159 final Activity activity) {
2160 ContextImpl appContext = new ContextImpl();
2161 appContext.init(r.packageInfo, r.token, this);
2162 appContext.setOuterContext(activity);
2163
2164 // For debugging purposes, if the activity's package name contains the value of
2165 // the "debug.use-second-display" system property as a substring, then show
2166 // its content on a secondary display if there is one.
2167 Context baseContext = appContext;
2168 String pkgName = SystemProperties.get("debug.second-display.pkg");
2169 if (pkgName != null && !pkgName.isEmpty()
2170 && r.packageInfo.mPackageName.contains(pkgName)) {
2171 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2172 for (int displayId : dm.getDisplayIds()) {
2173 if (displayId != Display.DEFAULT_DISPLAY) {
2174 Display display = dm.getRealDisplay(displayId);
2175 baseContext = appContext.createDisplayContext(display);
2176 break;
2177 }
2178 }
2179 }
2180 return baseContext;
2181 }
2182
Romain Guy65b345f2011-07-27 18:51:50 -07002183 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 // If we are getting ready to gc after going to the background, well
2185 // we are back active so skip it.
2186 unscheduleGcIdler();
2187
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002188 if (r.profileFd != null) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07002189 mProfiler.setProfiler(r.profileFile, r.profileFd);
2190 mProfiler.startProfiling();
2191 mProfiler.autoStopProfiler = r.autoStopProfiler;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002192 }
2193
Dianne Hackborn58f42a52011-10-10 13:46:34 -07002194 // Make sure we are running with the most recent config.
2195 handleConfigurationChanged(null, null);
2196
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002197 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002198 TAG, "Handling launch of " + r);
Christopher Tateb70f3df2009-04-07 16:07:59 -07002199 Activity a = performLaunchActivity(r, customIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002200
2201 if (a != null) {
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08002202 r.createdConfig = new Configuration(mConfiguration);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002203 Bundle oldState = r.state;
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002204 handleResumeActivity(r.token, false, r.isForward,
2205 !r.activity.mFinished && !r.startsNotResumed);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002206
2207 if (!r.activity.mFinished && r.startsNotResumed) {
2208 // The activity manager actually wants this one to start out
2209 // paused, because it needs to be visible but isn't in the
2210 // foreground. We accomplish this by going through the
2211 // normal startup (because activities expect to go through
2212 // onResume() the first time they run, before their window
2213 // is displayed), and then pausing it. However, in this case
2214 // we do -not- need to do the full pause cycle (of freezing
2215 // and such) because the activity manager assumes it can just
2216 // retain the current state it has.
2217 try {
2218 r.activity.mCalled = false;
2219 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002220 // We need to keep around the original state, in case
Dianne Hackborn03fcc332012-05-15 12:49:40 -07002221 // we need to be created again. But we only do this
2222 // for pre-Honeycomb apps, which always save their state
2223 // when pausing, so we can not have them save their state
2224 // when restarting from a paused state. For HC and later,
2225 // we want to (and can) let the state be saved as the normal
2226 // part of stopping the activity.
2227 if (r.isPreHoneycomb()) {
2228 r.state = oldState;
2229 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 if (!r.activity.mCalled) {
2231 throw new SuperNotCalledException(
2232 "Activity " + r.intent.getComponent().toShortString() +
2233 " did not call through to super.onPause()");
2234 }
2235
2236 } catch (SuperNotCalledException e) {
2237 throw e;
2238
2239 } catch (Exception e) {
2240 if (!mInstrumentation.onException(r.activity, e)) {
2241 throw new RuntimeException(
2242 "Unable to pause activity "
2243 + r.intent.getComponent().toShortString()
2244 + ": " + e.toString(), e);
2245 }
2246 }
2247 r.paused = true;
2248 }
2249 } else {
2250 // If there was an error, for any reason, tell the activity
2251 // manager to stop us.
2252 try {
2253 ActivityManagerNative.getDefault()
2254 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
2255 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07002256 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002257 }
2258 }
2259 }
2260
Romain Guy65b345f2011-07-27 18:51:50 -07002261 private void deliverNewIntents(ActivityClientRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 List<Intent> intents) {
2263 final int N = intents.size();
2264 for (int i=0; i<N; i++) {
2265 Intent intent = intents.get(i);
2266 intent.setExtrasClassLoader(r.activity.getClassLoader());
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002267 r.activity.mFragments.noteStateNotSaved();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002268 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2269 }
2270 }
2271
2272 public final void performNewIntents(IBinder token,
2273 List<Intent> intents) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002274 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002275 if (r != null) {
2276 final boolean resumed = !r.paused;
2277 if (resumed) {
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002278 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002279 mInstrumentation.callActivityOnPause(r.activity);
2280 }
2281 deliverNewIntents(r, intents);
2282 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07002283 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002284 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002285 }
2286 }
2287 }
Bob Leee5408332009-09-04 18:31:17 -07002288
Romain Guy65b345f2011-07-27 18:51:50 -07002289 private void handleNewIntent(NewIntentData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 performNewIntents(data.token, data.intents);
2291 }
2292
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002293 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2294
2295 /**
2296 * Return the Intent that's currently being handled by a
2297 * BroadcastReceiver on this thread, or null if none.
2298 * @hide
2299 */
2300 public static Intent getIntentBeingBroadcast() {
2301 return sCurrentBroadcastIntent.get();
2302 }
2303
Romain Guy65b345f2011-07-27 18:51:50 -07002304 private void handleReceiver(ReceiverData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002305 // If we are getting ready to gc after going to the background, well
2306 // we are back active so skip it.
2307 unscheduleGcIdler();
2308
2309 String component = data.intent.getComponent().getClassName();
2310
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002311 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002312 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313
2314 IActivityManager mgr = ActivityManagerNative.getDefault();
2315
Romain Guy65b345f2011-07-27 18:51:50 -07002316 BroadcastReceiver receiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 try {
2318 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2319 data.intent.setExtrasClassLoader(cl);
Dianne Hackborne829fef2010-10-26 17:44:01 -07002320 data.setExtrasClassLoader(cl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2322 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07002323 if (DEBUG_BROADCAST) Slog.i(TAG,
2324 "Finishing failed broadcast to " + data.intent.getComponent());
2325 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002326 throw new RuntimeException(
2327 "Unable to instantiate receiver " + component
2328 + ": " + e.toString(), e);
2329 }
2330
2331 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002332 Application app = packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07002333
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002334 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002335 TAG, "Performing receive of " + data.intent
2336 + ": app=" + app
2337 + ", appName=" + app.getPackageName()
2338 + ", pkg=" + packageInfo.getPackageName()
2339 + ", comp=" + data.intent.getComponent().toShortString()
2340 + ", dir=" + packageInfo.getAppDir());
2341
Dianne Hackborn21556372010-02-04 16:34:40 -08002342 ContextImpl context = (ContextImpl)app.getBaseContext();
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002343 sCurrentBroadcastIntent.set(data.intent);
Dianne Hackborne829fef2010-10-26 17:44:01 -07002344 receiver.setPendingResult(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 receiver.onReceive(context.getReceiverRestrictedContext(),
2346 data.intent);
2347 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07002348 if (DEBUG_BROADCAST) Slog.i(TAG,
2349 "Finishing failed broadcast to " + data.intent.getComponent());
2350 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002351 if (!mInstrumentation.onException(receiver, e)) {
2352 throw new RuntimeException(
2353 "Unable to start receiver " + component
2354 + ": " + e.toString(), e);
2355 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002356 } finally {
2357 sCurrentBroadcastIntent.set(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 }
2359
Dianne Hackborne829fef2010-10-26 17:44:01 -07002360 if (receiver.getPendingResult() != null) {
2361 data.finish();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002362 }
2363 }
2364
Christopher Tate181fafa2009-05-14 11:12:14 -07002365 // Instantiate a BackupAgent and tell it that it's alive
Romain Guy65b345f2011-07-27 18:51:50 -07002366 private void handleCreateBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002367 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002368
2369 // no longer idle; we have backup work to do
2370 unscheduleGcIdler();
2371
2372 // instantiate the BackupAgent class named in the manifest
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002373 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002374 String packageName = packageInfo.mPackageName;
2375 if (mBackupAgents.get(packageName) != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002376 Slog.d(TAG, "BackupAgent " + " for " + packageName
Christopher Tate181fafa2009-05-14 11:12:14 -07002377 + " already exists");
2378 return;
2379 }
Bob Leee5408332009-09-04 18:31:17 -07002380
Christopher Tate181fafa2009-05-14 11:12:14 -07002381 BackupAgent agent = null;
2382 String classname = data.appInfo.backupAgentName;
Christopher Tate4a627c72011-04-01 14:43:32 -07002383
Christopher Tate79ec80d2011-06-24 14:58:49 -07002384 // full backup operation but no app-supplied agent? use the default implementation
2385 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2386 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
Christopher Tate4a627c72011-04-01 14:43:32 -07002387 classname = "android.app.backup.FullBackupAgent";
Christopher Tate181fafa2009-05-14 11:12:14 -07002388 }
Christopher Tate4a627c72011-04-01 14:43:32 -07002389
Christopher Tate181fafa2009-05-14 11:12:14 -07002390 try {
Christopher Tated1475e02009-07-09 15:36:17 -07002391 IBinder binder = null;
2392 try {
Christopher Tate4a627c72011-04-01 14:43:32 -07002393 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2394
Christopher Tated1475e02009-07-09 15:36:17 -07002395 java.lang.ClassLoader cl = packageInfo.getClassLoader();
Christopher Tate4a627c72011-04-01 14:43:32 -07002396 agent = (BackupAgent) cl.loadClass(classname).newInstance();
Christopher Tated1475e02009-07-09 15:36:17 -07002397
2398 // set up the agent's context
Dianne Hackborn21556372010-02-04 16:34:40 -08002399 ContextImpl context = new ContextImpl();
Christopher Tated1475e02009-07-09 15:36:17 -07002400 context.init(packageInfo, null, this);
2401 context.setOuterContext(agent);
2402 agent.attach(context);
2403
2404 agent.onCreate();
2405 binder = agent.onBind();
2406 mBackupAgents.put(packageName, agent);
2407 } catch (Exception e) {
2408 // If this is during restore, fail silently; otherwise go
2409 // ahead and let the user see the crash.
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002410 Slog.e(TAG, "Agent threw during creation: " + e);
Christopher Tate75a99702011-05-18 16:28:19 -07002411 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2412 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
Christopher Tated1475e02009-07-09 15:36:17 -07002413 throw e;
2414 }
2415 // falling through with 'binder' still null
2416 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002417
2418 // tell the OS that we're live now
Christopher Tate181fafa2009-05-14 11:12:14 -07002419 try {
2420 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2421 } catch (RemoteException e) {
2422 // nothing to do.
2423 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002424 } catch (Exception e) {
2425 throw new RuntimeException("Unable to create BackupAgent "
Christopher Tate4a627c72011-04-01 14:43:32 -07002426 + classname + ": " + e.toString(), e);
Christopher Tate181fafa2009-05-14 11:12:14 -07002427 }
2428 }
2429
2430 // Tear down a BackupAgent
Romain Guy65b345f2011-07-27 18:51:50 -07002431 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002432 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
Bob Leee5408332009-09-04 18:31:17 -07002433
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002434 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002435 String packageName = packageInfo.mPackageName;
2436 BackupAgent agent = mBackupAgents.get(packageName);
2437 if (agent != null) {
2438 try {
2439 agent.onDestroy();
2440 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002441 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002442 e.printStackTrace();
2443 }
2444 mBackupAgents.remove(packageName);
2445 } else {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002446 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002447 }
2448 }
2449
Romain Guy65b345f2011-07-27 18:51:50 -07002450 private void handleCreateService(CreateServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002451 // If we are getting ready to gc after going to the background, well
2452 // we are back active so skip it.
2453 unscheduleGcIdler();
2454
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002455 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002456 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457 Service service = null;
2458 try {
2459 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2460 service = (Service) cl.loadClass(data.info.name).newInstance();
2461 } catch (Exception e) {
2462 if (!mInstrumentation.onException(service, e)) {
2463 throw new RuntimeException(
2464 "Unable to instantiate service " + data.info.name
2465 + ": " + e.toString(), e);
2466 }
2467 }
2468
2469 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002470 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002471
Dianne Hackborn21556372010-02-04 16:34:40 -08002472 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 context.init(packageInfo, null, this);
2474
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002475 Application app = packageInfo.makeApplication(false, mInstrumentation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002476 context.setOuterContext(service);
2477 service.attach(context, this, data.info.name, data.token, app,
2478 ActivityManagerNative.getDefault());
2479 service.onCreate();
2480 mServices.put(data.token, service);
2481 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002482 ActivityManagerNative.getDefault().serviceDoneExecuting(
2483 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002484 } catch (RemoteException e) {
2485 // nothing to do.
2486 }
2487 } catch (Exception e) {
2488 if (!mInstrumentation.onException(service, e)) {
2489 throw new RuntimeException(
2490 "Unable to create service " + data.info.name
2491 + ": " + e.toString(), e);
2492 }
2493 }
2494 }
2495
Romain Guy65b345f2011-07-27 18:51:50 -07002496 private void handleBindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002497 Service s = mServices.get(data.token);
Amith Yamasani742a6712011-05-04 14:49:28 -07002498 if (DEBUG_SERVICE)
2499 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002500 if (s != null) {
2501 try {
2502 data.intent.setExtrasClassLoader(s.getClassLoader());
2503 try {
2504 if (!data.rebind) {
2505 IBinder binder = s.onBind(data.intent);
2506 ActivityManagerNative.getDefault().publishService(
2507 data.token, data.intent, binder);
2508 } else {
2509 s.onRebind(data.intent);
2510 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002511 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002512 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002513 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002514 } catch (RemoteException ex) {
2515 }
2516 } catch (Exception e) {
2517 if (!mInstrumentation.onException(s, e)) {
2518 throw new RuntimeException(
2519 "Unable to bind to service " + s
2520 + " with " + data.intent + ": " + e.toString(), e);
2521 }
2522 }
2523 }
2524 }
2525
Romain Guy65b345f2011-07-27 18:51:50 -07002526 private void handleUnbindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002527 Service s = mServices.get(data.token);
2528 if (s != null) {
2529 try {
2530 data.intent.setExtrasClassLoader(s.getClassLoader());
2531 boolean doRebind = s.onUnbind(data.intent);
2532 try {
2533 if (doRebind) {
2534 ActivityManagerNative.getDefault().unbindFinished(
2535 data.token, data.intent, doRebind);
2536 } else {
2537 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002538 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002539 }
2540 } catch (RemoteException ex) {
2541 }
2542 } catch (Exception e) {
2543 if (!mInstrumentation.onException(s, e)) {
2544 throw new RuntimeException(
2545 "Unable to unbind to service " + s
2546 + " with " + data.intent + ": " + e.toString(), e);
2547 }
2548 }
2549 }
2550 }
2551
Dianne Hackborn625ac272010-09-17 18:29:22 -07002552 private void handleDumpService(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002553 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2554 try {
2555 Service s = mServices.get(info.token);
2556 if (s != null) {
2557 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2558 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2559 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002561 } finally {
2562 IoUtils.closeQuietly(info.fd);
2563 StrictMode.setThreadPolicy(oldPolicy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 }
2565 }
2566
Dianne Hackborn625ac272010-09-17 18:29:22 -07002567 private void handleDumpActivity(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002568 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2569 try {
2570 ActivityClientRecord r = mActivities.get(info.token);
2571 if (r != null && r.activity != null) {
2572 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2573 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2574 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07002575 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002576 } finally {
2577 IoUtils.closeQuietly(info.fd);
2578 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackborn625ac272010-09-17 18:29:22 -07002579 }
2580 }
2581
Marco Nelissen18cb2872011-11-15 11:19:53 -08002582 private void handleDumpProvider(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002583 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2584 try {
2585 ProviderClientRecord r = mLocalProviders.get(info.token);
2586 if (r != null && r.mLocalProvider != null) {
2587 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2588 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2589 pw.flush();
Marco Nelissen18cb2872011-11-15 11:19:53 -08002590 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002591 } finally {
2592 IoUtils.closeQuietly(info.fd);
2593 StrictMode.setThreadPolicy(oldPolicy);
Marco Nelissen18cb2872011-11-15 11:19:53 -08002594 }
2595 }
2596
Romain Guy65b345f2011-07-27 18:51:50 -07002597 private void handleServiceArgs(ServiceArgsData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002598 Service s = mServices.get(data.token);
2599 if (s != null) {
2600 try {
2601 if (data.args != null) {
2602 data.args.setExtrasClassLoader(s.getClassLoader());
2603 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002604 int res;
2605 if (!data.taskRemoved) {
2606 res = s.onStartCommand(data.args, data.flags, data.startId);
2607 } else {
2608 s.onTaskRemoved(data.args);
2609 res = Service.START_TASK_REMOVED_COMPLETE;
2610 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002611
2612 QueuedWork.waitToFinish();
2613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002615 ActivityManagerNative.getDefault().serviceDoneExecuting(
2616 data.token, 1, data.startId, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002617 } catch (RemoteException e) {
2618 // nothing to do.
2619 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002620 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002621 } catch (Exception e) {
2622 if (!mInstrumentation.onException(s, e)) {
2623 throw new RuntimeException(
2624 "Unable to start service " + s
2625 + " with " + data.args + ": " + e.toString(), e);
2626 }
2627 }
2628 }
2629 }
2630
Romain Guy65b345f2011-07-27 18:51:50 -07002631 private void handleStopService(IBinder token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002632 Service s = mServices.remove(token);
2633 if (s != null) {
2634 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002635 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002636 s.onDestroy();
2637 Context context = s.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002638 if (context instanceof ContextImpl) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 final String who = s.getClassName();
Dianne Hackborn21556372010-02-04 16:34:40 -08002640 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002641 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002642
2643 QueuedWork.waitToFinish();
2644
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002645 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002646 ActivityManagerNative.getDefault().serviceDoneExecuting(
2647 token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 } catch (RemoteException e) {
2649 // nothing to do.
2650 }
2651 } catch (Exception e) {
2652 if (!mInstrumentation.onException(s, e)) {
2653 throw new RuntimeException(
2654 "Unable to stop service " + s
2655 + ": " + e.toString(), e);
2656 }
2657 }
2658 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002659 //Slog.i(TAG, "Running services: " + mServices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002660 }
2661
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002662 public final ActivityClientRecord performResumeActivity(IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002663 boolean clearHide) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002664 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002665 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002666 + " finished=" + r.activity.mFinished);
2667 if (r != null && !r.activity.mFinished) {
2668 if (clearHide) {
2669 r.hideForNow = false;
2670 r.activity.mStartedActivity = false;
2671 }
2672 try {
2673 if (r.pendingIntents != null) {
2674 deliverNewIntents(r, r.pendingIntents);
2675 r.pendingIntents = null;
2676 }
2677 if (r.pendingResults != null) {
2678 deliverResults(r, r.pendingResults);
2679 r.pendingResults = null;
2680 }
2681 r.activity.performResume();
2682
Bob Leee5408332009-09-04 18:31:17 -07002683 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002684 r.activity.getComponentName().getClassName());
Bob Leee5408332009-09-04 18:31:17 -07002685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 r.paused = false;
2687 r.stopped = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688 r.state = null;
2689 } catch (Exception e) {
2690 if (!mInstrumentation.onException(r.activity, e)) {
2691 throw new RuntimeException(
2692 "Unable to resume activity "
2693 + r.intent.getComponent().toShortString()
2694 + ": " + e.toString(), e);
2695 }
2696 }
2697 }
2698 return r;
2699 }
2700
Romain Guya998dff2012-03-23 18:58:36 -07002701 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002702 if (r.mPendingRemoveWindow != null) {
2703 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2704 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2705 if (wtoken != null) {
Jeff Brown98365d72012-08-19 20:30:52 -07002706 WindowManagerGlobal.getInstance().closeAll(wtoken,
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002707 r.activity.getClass().getName(), "Activity");
2708 }
2709 }
2710 r.mPendingRemoveWindow = null;
2711 r.mPendingRemoveWindowManager = null;
2712 }
2713
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002714 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2715 boolean reallyResume) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 // If we are getting ready to gc after going to the background, well
2717 // we are back active so skip it.
2718 unscheduleGcIdler();
2719
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002720 ActivityClientRecord r = performResumeActivity(token, clearHide);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721
2722 if (r != null) {
2723 final Activity a = r.activity;
2724
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002725 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 TAG, "Resume " + r + " started activity: " +
2727 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2728 + ", finished: " + a.mFinished);
2729
2730 final int forwardBit = isForward ?
2731 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
Bob Leee5408332009-09-04 18:31:17 -07002732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 // If the window hasn't yet been added to the window manager,
2734 // and this guy didn't finish itself or start another activity,
2735 // then go ahead and add the window.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002736 boolean willBeVisible = !a.mStartedActivity;
2737 if (!willBeVisible) {
2738 try {
2739 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2740 a.getActivityToken());
2741 } catch (RemoteException e) {
2742 }
2743 }
2744 if (r.window == null && !a.mFinished && willBeVisible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002745 r.window = r.activity.getWindow();
2746 View decor = r.window.getDecorView();
2747 decor.setVisibility(View.INVISIBLE);
2748 ViewManager wm = a.getWindowManager();
2749 WindowManager.LayoutParams l = r.window.getAttributes();
2750 a.mDecor = decor;
2751 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2752 l.softInputMode |= forwardBit;
2753 if (a.mVisibleFromClient) {
2754 a.mWindowAdded = true;
2755 wm.addView(decor, l);
2756 }
2757
2758 // If the window has already been added, but during resume
2759 // we started another activity, then don't yet make the
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002760 // window visible.
2761 } else if (!willBeVisible) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002762 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002763 TAG, "Launch " + r + " mStartedActivity set");
2764 r.hideForNow = true;
2765 }
2766
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002767 // Get rid of anything left hanging around.
2768 cleanUpPendingRemoveWindows(r);
2769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002770 // The window is now visible if it has been added, we are not
2771 // simply finishing, and we are not starting another activity.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002772 if (!r.activity.mFinished && willBeVisible
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002773 && r.activity.mDecor != null && !r.hideForNow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002775 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002776 + r.activityInfo.name + " with newConfig " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 performConfigurationChanged(r.activity, r.newConfig);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07002778 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002779 r.newConfig = null;
2780 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002781 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002782 + isForward);
2783 WindowManager.LayoutParams l = r.window.getAttributes();
2784 if ((l.softInputMode
2785 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2786 != forwardBit) {
2787 l.softInputMode = (l.softInputMode
2788 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2789 | forwardBit;
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002790 if (r.activity.mVisibleFromClient) {
2791 ViewManager wm = a.getWindowManager();
2792 View decor = r.window.getDecorView();
2793 wm.updateViewLayout(decor, l);
2794 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795 }
2796 r.activity.mVisibleFromServer = true;
2797 mNumVisibleActivities++;
2798 if (r.activity.mVisibleFromClient) {
2799 r.activity.makeVisible();
2800 }
2801 }
2802
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002803 if (!r.onlyLocalRequest) {
2804 r.nextIdle = mNewActivities;
2805 mNewActivities = r;
2806 if (localLOGV) Slog.v(
2807 TAG, "Scheduling idle handler for " + r);
2808 Looper.myQueue().addIdleHandler(new Idler());
2809 }
2810 r.onlyLocalRequest = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002811
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002812 // Tell the activity manager we have resumed.
2813 if (reallyResume) {
2814 try {
2815 ActivityManagerNative.getDefault().activityResumed(token);
2816 } catch (RemoteException ex) {
2817 }
2818 }
2819
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002820 } else {
2821 // If an exception was thrown when trying to resume, then
2822 // just end this activity.
2823 try {
2824 ActivityManagerNative.getDefault()
2825 .finishActivity(token, Activity.RESULT_CANCELED, null);
2826 } catch (RemoteException ex) {
2827 }
2828 }
2829 }
2830
2831 private int mThumbnailWidth = -1;
2832 private int mThumbnailHeight = -1;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002833 private Bitmap mAvailThumbnailBitmap = null;
2834 private Canvas mThumbnailCanvas = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002835
Romain Guy65b345f2011-07-27 18:51:50 -07002836 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002837 Bitmap thumbnail = mAvailThumbnailBitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002839 if (thumbnail == null) {
2840 int w = mThumbnailWidth;
2841 int h;
2842 if (w < 0) {
2843 Resources res = r.activity.getResources();
2844 mThumbnailHeight = h =
2845 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002846
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002847 mThumbnailWidth = w =
2848 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2849 } else {
2850 h = mThumbnailHeight;
2851 }
2852
2853 // On platforms where we don't want thumbnails, set dims to (0,0)
2854 if ((w > 0) && (h > 0)) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07002855 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
2856 w, h, THUMBNAIL_FORMAT);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002857 thumbnail.eraseColor(0);
2858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 }
2860
Dianne Hackbornfb3806d2010-12-09 13:14:12 -08002861 if (thumbnail != null) {
2862 Canvas cv = mThumbnailCanvas;
2863 if (cv == null) {
2864 mThumbnailCanvas = cv = new Canvas();
2865 }
2866
2867 cv.setBitmap(thumbnail);
2868 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2869 mAvailThumbnailBitmap = thumbnail;
2870 thumbnail = null;
2871 }
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07002872 cv.setBitmap(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002873 }
Jim Miller0b2a6d02010-07-13 18:01:29 -07002874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875 } catch (Exception e) {
2876 if (!mInstrumentation.onException(r.activity, e)) {
2877 throw new RuntimeException(
2878 "Unable to create thumbnail of "
2879 + r.intent.getComponent().toShortString()
2880 + ": " + e.toString(), e);
2881 }
2882 thumbnail = null;
2883 }
2884
2885 return thumbnail;
2886 }
2887
Romain Guy65b345f2011-07-27 18:51:50 -07002888 private void handlePauseActivity(IBinder token, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 boolean userLeaving, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002890 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002891 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002892 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002893 if (userLeaving) {
2894 performUserLeavingActivity(r);
2895 }
Bob Leee5408332009-09-04 18:31:17 -07002896
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002897 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002898 performPauseActivity(token, finished, r.isPreHoneycomb());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002899
Dianne Hackbornaa93bcd2010-10-27 13:57:00 -07002900 // Make sure any pending writes are now committed.
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002901 if (r.isPreHoneycomb()) {
2902 QueuedWork.waitToFinish();
2903 }
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002905 // Tell the activity manager we have paused.
2906 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002907 ActivityManagerNative.getDefault().activityPaused(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002908 } catch (RemoteException ex) {
2909 }
2910 }
2911 }
2912
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002913 final void performUserLeavingActivity(ActivityClientRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002914 mInstrumentation.callActivityOnUserLeaving(r.activity);
2915 }
2916
2917 final Bundle performPauseActivity(IBinder token, boolean finished,
2918 boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002919 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002920 return r != null ? performPauseActivity(r, finished, saveState) : null;
2921 }
2922
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002923 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 boolean saveState) {
2925 if (r.paused) {
2926 if (r.activity.mFinished) {
2927 // If we are finishing, we won't call onResume() in certain cases.
2928 // So here we likewise don't want to call onPause() if the activity
2929 // isn't resumed.
2930 return null;
2931 }
2932 RuntimeException e = new RuntimeException(
2933 "Performing pause of activity that is not resumed: "
2934 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002935 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002936 }
2937 Bundle state = null;
2938 if (finished) {
2939 r.activity.mFinished = true;
2940 }
2941 try {
2942 // Next have the activity save its current state and managed dialogs...
2943 if (!r.activity.mFinished && saveState) {
2944 state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04002945 state.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002946 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2947 r.state = state;
2948 }
2949 // Now we are idle.
2950 r.activity.mCalled = false;
2951 mInstrumentation.callActivityOnPause(r.activity);
2952 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
2953 if (!r.activity.mCalled) {
2954 throw new SuperNotCalledException(
2955 "Activity " + r.intent.getComponent().toShortString() +
2956 " did not call through to super.onPause()");
2957 }
2958
2959 } catch (SuperNotCalledException e) {
2960 throw e;
2961
2962 } catch (Exception e) {
2963 if (!mInstrumentation.onException(r.activity, e)) {
2964 throw new RuntimeException(
2965 "Unable to pause activity "
2966 + r.intent.getComponent().toShortString()
2967 + ": " + e.toString(), e);
2968 }
2969 }
2970 r.paused = true;
Jeff Hamilton52d32032011-01-08 15:31:26 -06002971
2972 // Notify any outstanding on paused listeners
2973 ArrayList<OnActivityPausedListener> listeners;
2974 synchronized (mOnPauseListeners) {
2975 listeners = mOnPauseListeners.remove(r.activity);
2976 }
2977 int size = (listeners != null ? listeners.size() : 0);
2978 for (int i = 0; i < size; i++) {
2979 listeners.get(i).onPaused(r.activity);
2980 }
2981
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002982 return state;
2983 }
2984
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002985 final void performStopActivity(IBinder token, boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002986 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002987 performStopActivityInner(r, null, false, saveState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002988 }
2989
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07002990 private static class StopInfo implements Runnable {
2991 ActivityClientRecord activity;
2992 Bundle state;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002993 Bitmap thumbnail;
2994 CharSequence description;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07002995
2996 @Override public void run() {
2997 // Tell activity manager we have been stopped.
2998 try {
2999 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3000 ActivityManagerNative.getDefault().activityStopped(
3001 activity.token, state, thumbnail, description);
3002 } catch (RemoteException ex) {
3003 }
3004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 }
3006
Jeff Brownddaa9ac2011-11-11 20:16:14 -08003007 private static final class ProviderRefCount {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003008 public final IActivityManager.ContentProviderHolder holder;
3009 public final ProviderClientRecord client;
3010 public int stableCount;
3011 public int unstableCount;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08003012
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003013 // When this is set, the stable and unstable ref counts are 0 and
3014 // we have a pending operation scheduled to remove the ref count
3015 // from the activity manager. On the activity manager we are still
3016 // holding an unstable ref, though it is not reflected in the counts
3017 // here.
3018 public boolean removePending;
3019
3020 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3021 ProviderClientRecord inClient, int sCount, int uCount) {
3022 holder = inHolder;
3023 client = inClient;
3024 stableCount = sCount;
3025 unstableCount = uCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003026 }
3027 }
3028
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003029 /**
3030 * Core implementation of stopping an activity. Note this is a little
3031 * tricky because the server's meaning of stop is slightly different
3032 * than our client -- for the server, stop means to save state and give
3033 * it the result when it is done, but the window may still be visible.
3034 * For the client, we want to call onStop()/onStart() to indicate when
3035 * the activity's UI visibillity changes.
3036 */
Romain Guy65b345f2011-07-27 18:51:50 -07003037 private void performStopActivityInner(ActivityClientRecord r,
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003038 StopInfo info, boolean keepShown, boolean saveState) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003039 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003040 Bundle state = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 if (r != null) {
3042 if (!keepShown && r.stopped) {
3043 if (r.activity.mFinished) {
3044 // If we are finishing, we won't call onResume() in certain
3045 // cases. So here we likewise don't want to call onStop()
3046 // if the activity isn't resumed.
3047 return;
3048 }
3049 RuntimeException e = new RuntimeException(
3050 "Performing stop of activity that is not resumed: "
3051 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003052 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053 }
3054
3055 if (info != null) {
3056 try {
3057 // First create a thumbnail for the activity...
Dianne Hackborn0500b3c2011-11-01 15:28:43 -07003058 // For now, don't create the thumbnail here; we are
3059 // doing that by doing a screen snapshot.
3060 info.thumbnail = null; //createThumbnailBitmap(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 info.description = r.activity.onCreateDescription();
3062 } catch (Exception e) {
3063 if (!mInstrumentation.onException(r.activity, e)) {
3064 throw new RuntimeException(
3065 "Unable to save state of activity "
3066 + r.intent.getComponent().toShortString()
3067 + ": " + e.toString(), e);
3068 }
3069 }
3070 }
3071
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003072 // Next have the activity save its current state and managed dialogs...
3073 if (!r.activity.mFinished && saveState) {
3074 if (r.state == null) {
3075 state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04003076 state.setAllowFds(false);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003077 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3078 r.state = state;
3079 } else {
3080 state = r.state;
3081 }
3082 }
3083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 if (!keepShown) {
3085 try {
3086 // Now we are idle.
3087 r.activity.performStop();
3088 } catch (Exception e) {
3089 if (!mInstrumentation.onException(r.activity, e)) {
3090 throw new RuntimeException(
3091 "Unable to stop activity "
3092 + r.intent.getComponent().toShortString()
3093 + ": " + e.toString(), e);
3094 }
3095 }
3096 r.stopped = true;
3097 }
3098
3099 r.paused = true;
3100 }
3101 }
3102
Romain Guy65b345f2011-07-27 18:51:50 -07003103 private void updateVisibility(ActivityClientRecord r, boolean show) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003104 View v = r.activity.mDecor;
3105 if (v != null) {
3106 if (show) {
3107 if (!r.activity.mVisibleFromServer) {
3108 r.activity.mVisibleFromServer = true;
3109 mNumVisibleActivities++;
3110 if (r.activity.mVisibleFromClient) {
3111 r.activity.makeVisible();
3112 }
3113 }
3114 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003115 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003116 + r.activityInfo.name + " with new config " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003117 performConfigurationChanged(r.activity, r.newConfig);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003118 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003119 r.newConfig = null;
3120 }
3121 } else {
3122 if (r.activity.mVisibleFromServer) {
3123 r.activity.mVisibleFromServer = false;
3124 mNumVisibleActivities--;
3125 v.setVisibility(View.INVISIBLE);
3126 }
3127 }
3128 }
3129 }
3130
Romain Guy65b345f2011-07-27 18:51:50 -07003131 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003132 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003133 r.activity.mConfigChangeFlags |= configChanges;
3134
3135 StopInfo info = new StopInfo();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003136 performStopActivityInner(r, info, show, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003137
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003138 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003139 TAG, "Finishing stop of " + r + ": show=" + show
3140 + " win=" + r.window);
3141
3142 updateVisibility(r, show);
Bob Leee5408332009-09-04 18:31:17 -07003143
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08003144 // Make sure any pending writes are now committed.
3145 if (!r.isPreHoneycomb()) {
3146 QueuedWork.waitToFinish();
3147 }
3148
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07003149 // Schedule the call to tell the activity manager we have
3150 // stopped. We don't do this immediately, because we want to
3151 // have a chance for any other pending work (in particular memory
3152 // trim requests) to complete before you tell the activity
3153 // manager to proceed and allow us to go fully into the background.
3154 info.activity = r;
3155 info.state = r.state;
3156 mH.post(info);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 }
3158
3159 final void performRestartActivity(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003160 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003161 if (r.stopped) {
3162 r.activity.performRestart();
3163 r.stopped = false;
3164 }
3165 }
3166
Romain Guy65b345f2011-07-27 18:51:50 -07003167 private void handleWindowVisibility(IBinder token, boolean show) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003168 ActivityClientRecord r = mActivities.get(token);
Dianne Hackbornbfddc0f2010-12-14 11:28:01 -08003169
3170 if (r == null) {
3171 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3172 return;
3173 }
3174
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003175 if (!show && !r.stopped) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003176 performStopActivityInner(r, null, show, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003177 } else if (show && r.stopped) {
3178 // If we are getting ready to gc after going to the background, well
3179 // we are back active so skip it.
3180 unscheduleGcIdler();
3181
3182 r.activity.performRestart();
3183 r.stopped = false;
3184 }
3185 if (r.activity.mDecor != null) {
Joe Onorato43a17652011-04-06 19:22:23 -07003186 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003187 TAG, "Handle window " + r + " visibility: " + show);
3188 updateVisibility(r, show);
3189 }
3190 }
3191
Romain Guy65b345f2011-07-27 18:51:50 -07003192 private void handleSleeping(IBinder token, boolean sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003193 ActivityClientRecord r = mActivities.get(token);
3194
3195 if (r == null) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08003196 Log.w(TAG, "handleSleeping: no activity for token " + token);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003197 return;
3198 }
3199
3200 if (sleeping) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08003201 if (!r.stopped && !r.isPreHoneycomb()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003202 try {
3203 // Now we are idle.
3204 r.activity.performStop();
3205 } catch (Exception e) {
3206 if (!mInstrumentation.onException(r.activity, e)) {
3207 throw new RuntimeException(
3208 "Unable to stop activity "
3209 + r.intent.getComponent().toShortString()
3210 + ": " + e.toString(), e);
3211 }
3212 }
3213 r.stopped = true;
3214 }
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08003215
3216 // Make sure any pending writes are now committed.
3217 if (!r.isPreHoneycomb()) {
3218 QueuedWork.waitToFinish();
3219 }
3220
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003221 // Tell activity manager we slept.
3222 try {
3223 ActivityManagerNative.getDefault().activitySlept(r.token);
3224 } catch (RemoteException ex) {
3225 }
3226 } else {
3227 if (r.stopped && r.activity.mVisibleFromServer) {
3228 r.activity.performRestart();
3229 r.stopped = false;
3230 }
3231 }
3232 }
3233
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003234 private void handleSetCoreSettings(Bundle coreSettings) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08003235 synchronized (mPackages) {
3236 mCoreSettings = coreSettings;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003237 }
3238 }
3239
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003240 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3241 LoadedApk apk = peekPackageInfo(data.pkg, false);
3242 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003243 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003244 }
3245 apk = peekPackageInfo(data.pkg, true);
3246 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003247 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003248 }
3249 handleConfigurationChanged(mConfiguration, data.info);
Jeff Brown98365d72012-08-19 20:30:52 -07003250 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003251 }
3252
Romain Guy65b345f2011-07-27 18:51:50 -07003253 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003254 final int N = results.size();
3255 for (int i=0; i<N; i++) {
3256 ResultInfo ri = results.get(i);
3257 try {
3258 if (ri.mData != null) {
3259 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3260 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003261 if (DEBUG_RESULTS) Slog.v(TAG,
Chris Tate8a7dc172009-03-24 20:11:42 -07003262 "Delivering result to activity " + r + " : " + ri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003263 r.activity.dispatchActivityResult(ri.mResultWho,
3264 ri.mRequestCode, ri.mResultCode, ri.mData);
3265 } catch (Exception e) {
3266 if (!mInstrumentation.onException(r.activity, e)) {
3267 throw new RuntimeException(
3268 "Failure delivering result " + ri + " to activity "
3269 + r.intent.getComponent().toShortString()
3270 + ": " + e.toString(), e);
3271 }
3272 }
3273 }
3274 }
3275
Romain Guy65b345f2011-07-27 18:51:50 -07003276 private void handleSendResult(ResultData res) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003277 ActivityClientRecord r = mActivities.get(res.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003278 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003279 if (r != null) {
3280 final boolean resumed = !r.paused;
3281 if (!r.activity.mFinished && r.activity.mDecor != null
3282 && r.hideForNow && resumed) {
3283 // We had hidden the activity because it started another
3284 // one... we have gotten a result back and we are not
3285 // paused, so make sure our window is visible.
3286 updateVisibility(r, true);
3287 }
3288 if (resumed) {
3289 try {
3290 // Now we are idle.
3291 r.activity.mCalled = false;
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07003292 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003293 mInstrumentation.callActivityOnPause(r.activity);
3294 if (!r.activity.mCalled) {
3295 throw new SuperNotCalledException(
3296 "Activity " + r.intent.getComponent().toShortString()
3297 + " did not call through to super.onPause()");
3298 }
3299 } catch (SuperNotCalledException e) {
3300 throw e;
3301 } catch (Exception e) {
3302 if (!mInstrumentation.onException(r.activity, e)) {
3303 throw new RuntimeException(
3304 "Unable to pause activity "
3305 + r.intent.getComponent().toShortString()
3306 + ": " + e.toString(), e);
3307 }
3308 }
3309 }
3310 deliverResults(r, res.results);
3311 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07003312 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07003313 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003314 }
3315 }
3316 }
3317
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003318 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003319 return performDestroyActivity(token, finishing, 0, false);
3320 }
3321
Romain Guy65b345f2011-07-27 18:51:50 -07003322 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003323 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003324 ActivityClientRecord r = mActivities.get(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003325 Class activityClass = null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003326 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003327 if (r != null) {
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003328 activityClass = r.activity.getClass();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329 r.activity.mConfigChangeFlags |= configChanges;
3330 if (finishing) {
3331 r.activity.mFinished = true;
3332 }
3333 if (!r.paused) {
3334 try {
3335 r.activity.mCalled = false;
3336 mInstrumentation.callActivityOnPause(r.activity);
Bob Leee5408332009-09-04 18:31:17 -07003337 EventLog.writeEvent(LOG_ON_PAUSE_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 r.activity.getComponentName().getClassName());
3339 if (!r.activity.mCalled) {
3340 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003341 "Activity " + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003342 + " did not call through to super.onPause()");
3343 }
3344 } catch (SuperNotCalledException e) {
3345 throw e;
3346 } catch (Exception e) {
3347 if (!mInstrumentation.onException(r.activity, e)) {
3348 throw new RuntimeException(
3349 "Unable to pause activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003350 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003351 + ": " + e.toString(), e);
3352 }
3353 }
3354 r.paused = true;
3355 }
3356 if (!r.stopped) {
3357 try {
3358 r.activity.performStop();
3359 } catch (SuperNotCalledException e) {
3360 throw e;
3361 } catch (Exception e) {
3362 if (!mInstrumentation.onException(r.activity, e)) {
3363 throw new RuntimeException(
3364 "Unable to stop activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003365 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 + ": " + e.toString(), e);
3367 }
3368 }
3369 r.stopped = true;
3370 }
3371 if (getNonConfigInstance) {
3372 try {
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07003373 r.lastNonConfigurationInstances
3374 = r.activity.retainNonConfigurationInstances();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 } catch (Exception e) {
3376 if (!mInstrumentation.onException(r.activity, e)) {
3377 throw new RuntimeException(
3378 "Unable to retain activity "
3379 + r.intent.getComponent().toShortString()
3380 + ": " + e.toString(), e);
3381 }
3382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 }
3384 try {
3385 r.activity.mCalled = false;
Dianne Hackborn2dedce62010-04-15 14:45:25 -07003386 mInstrumentation.callActivityOnDestroy(r.activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003387 if (!r.activity.mCalled) {
3388 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003389 "Activity " + safeToComponentShortString(r.intent) +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 " did not call through to super.onDestroy()");
3391 }
3392 if (r.window != null) {
3393 r.window.closeAllPanels();
3394 }
3395 } catch (SuperNotCalledException e) {
3396 throw e;
3397 } catch (Exception e) {
3398 if (!mInstrumentation.onException(r.activity, e)) {
3399 throw new RuntimeException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003400 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3401 + ": " + e.toString(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003402 }
3403 }
3404 }
3405 mActivities.remove(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003406 StrictMode.decrementExpectedActivityCount(activityClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003407 return r;
3408 }
3409
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003410 private static String safeToComponentShortString(Intent intent) {
3411 ComponentName component = intent.getComponent();
3412 return component == null ? "[Unknown]" : component.toShortString();
3413 }
3414
Romain Guy65b345f2011-07-27 18:51:50 -07003415 private void handleDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003416 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003417 ActivityClientRecord r = performDestroyActivity(token, finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 configChanges, getNonConfigInstance);
3419 if (r != null) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003420 cleanUpPendingRemoveWindows(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003421 WindowManager wm = r.activity.getWindowManager();
3422 View v = r.activity.mDecor;
3423 if (v != null) {
3424 if (r.activity.mVisibleFromServer) {
3425 mNumVisibleActivities--;
3426 }
3427 IBinder wtoken = v.getWindowToken();
3428 if (r.activity.mWindowAdded) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003429 if (r.onlyLocalRequest) {
3430 // Hold off on removing this until the new activity's
3431 // window is being added.
3432 r.mPendingRemoveWindow = v;
3433 r.mPendingRemoveWindowManager = wm;
3434 } else {
3435 wm.removeViewImmediate(v);
3436 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003437 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003438 if (wtoken != null && r.mPendingRemoveWindow == null) {
Jeff Brown98365d72012-08-19 20:30:52 -07003439 WindowManagerGlobal.getInstance().closeAll(wtoken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003440 r.activity.getClass().getName(), "Activity");
3441 }
3442 r.activity.mDecor = null;
3443 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003444 if (r.mPendingRemoveWindow == null) {
3445 // If we are delaying the removal of the activity window, then
3446 // we can't clean up all windows here. Note that we can't do
3447 // so later either, which means any windows that aren't closed
3448 // by the app will leak. Well we try to warning them a lot
3449 // about leaking windows, because that is a bug, so if they are
3450 // using this recreate facility then they get to live with leaks.
Jeff Brown98365d72012-08-19 20:30:52 -07003451 WindowManagerGlobal.getInstance().closeAll(token,
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003452 r.activity.getClass().getName(), "Activity");
3453 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454
3455 // Mocked out contexts won't be participating in the normal
3456 // process lifecycle, but if we're running with a proper
3457 // ApplicationContext we need to have it tear down things
3458 // cleanly.
3459 Context c = r.activity.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08003460 if (c instanceof ContextImpl) {
3461 ((ContextImpl) c).scheduleFinalCleanup(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003462 r.activity.getClass().getName(), "Activity");
3463 }
3464 }
3465 if (finishing) {
3466 try {
3467 ActivityManagerNative.getDefault().activityDestroyed(token);
3468 } catch (RemoteException ex) {
3469 // If the system process has died, it's game over for everyone.
3470 }
3471 }
3472 }
3473
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003474 public final void requestRelaunchActivity(IBinder token,
3475 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3476 int configChanges, boolean notResumed, Configuration config,
3477 boolean fromServer) {
3478 ActivityClientRecord target = null;
3479
3480 synchronized (mPackages) {
3481 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3482 ActivityClientRecord r = mRelaunchingActivities.get(i);
3483 if (r.token == token) {
3484 target = r;
3485 if (pendingResults != null) {
3486 if (r.pendingResults != null) {
3487 r.pendingResults.addAll(pendingResults);
3488 } else {
3489 r.pendingResults = pendingResults;
3490 }
3491 }
3492 if (pendingNewIntents != null) {
3493 if (r.pendingIntents != null) {
3494 r.pendingIntents.addAll(pendingNewIntents);
3495 } else {
3496 r.pendingIntents = pendingNewIntents;
3497 }
3498 }
3499 break;
3500 }
3501 }
3502
3503 if (target == null) {
3504 target = new ActivityClientRecord();
3505 target.token = token;
3506 target.pendingResults = pendingResults;
3507 target.pendingIntents = pendingNewIntents;
3508 if (!fromServer) {
3509 ActivityClientRecord existing = mActivities.get(token);
3510 if (existing != null) {
3511 target.startsNotResumed = existing.paused;
3512 }
3513 target.onlyLocalRequest = true;
3514 }
3515 mRelaunchingActivities.add(target);
3516 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
3517 }
3518
3519 if (fromServer) {
3520 target.startsNotResumed = notResumed;
3521 target.onlyLocalRequest = false;
3522 }
3523 if (config != null) {
3524 target.createdConfig = config;
3525 }
3526 target.pendingConfigChanges |= configChanges;
3527 }
3528 }
3529
Romain Guy65b345f2011-07-27 18:51:50 -07003530 private void handleRelaunchActivity(ActivityClientRecord tmp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531 // If we are getting ready to gc after going to the background, well
3532 // we are back active so skip it.
3533 unscheduleGcIdler();
3534
3535 Configuration changedConfig = null;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003536 int configChanges = 0;
Bob Leee5408332009-09-04 18:31:17 -07003537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003538 // First: make sure we have the most recent configuration and most
3539 // recent version of the activity, or skip it if some previous call
3540 // had taken a more recent version.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003541 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003542 int N = mRelaunchingActivities.size();
3543 IBinder token = tmp.token;
3544 tmp = null;
3545 for (int i=0; i<N; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003546 ActivityClientRecord r = mRelaunchingActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547 if (r.token == token) {
3548 tmp = r;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003549 configChanges |= tmp.pendingConfigChanges;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003550 mRelaunchingActivities.remove(i);
3551 i--;
3552 N--;
3553 }
3554 }
Bob Leee5408332009-09-04 18:31:17 -07003555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003556 if (tmp == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003557 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 return;
3559 }
Bob Leee5408332009-09-04 18:31:17 -07003560
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003561 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3562 + tmp.token + " with configChanges=0x"
3563 + Integer.toHexString(configChanges));
3564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003565 if (mPendingConfiguration != null) {
3566 changedConfig = mPendingConfiguration;
3567 mPendingConfiguration = null;
3568 }
3569 }
Bob Leee5408332009-09-04 18:31:17 -07003570
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003571 if (tmp.createdConfig != null) {
3572 // If the activity manager is passing us its current config,
3573 // assume that is really what we want regardless of what we
3574 // may have pending.
3575 if (mConfiguration == null
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003576 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3577 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3578 if (changedConfig == null
3579 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3580 changedConfig = tmp.createdConfig;
3581 }
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003582 }
3583 }
3584
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003585 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003586 + tmp.token + ": changedConfig=" + changedConfig);
3587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003588 // If there was a pending configuration change, execute it first.
3589 if (changedConfig != null) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003590 mCurDefaultDisplayDpi = changedConfig.densityDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -07003591 updateDefaultDensity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003592 handleConfigurationChanged(changedConfig, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003593 }
Bob Leee5408332009-09-04 18:31:17 -07003594
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003595 ActivityClientRecord r = mActivities.get(tmp.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003596 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003597 if (r == null) {
3598 return;
3599 }
Bob Leee5408332009-09-04 18:31:17 -07003600
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003601 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003602 r.onlyLocalRequest = tmp.onlyLocalRequest;
Christopher Tateb70f3df2009-04-07 16:07:59 -07003603 Intent currentIntent = r.activity.mIntent;
Bob Leee5408332009-09-04 18:31:17 -07003604
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003605 r.activity.mChangingConfigurations = true;
3606
Dianne Hackborne2b04802010-12-09 09:24:55 -08003607 // Need to ensure state is saved.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003608 if (!r.paused) {
Dianne Hackborne2b04802010-12-09 09:24:55 -08003609 performPauseActivity(r.token, false, r.isPreHoneycomb());
3610 }
3611 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3612 r.state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04003613 r.state.setAllowFds(false);
Dianne Hackborne2b04802010-12-09 09:24:55 -08003614 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 }
Bob Leee5408332009-09-04 18:31:17 -07003616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 handleDestroyActivity(r.token, false, configChanges, true);
Bob Leee5408332009-09-04 18:31:17 -07003618
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003619 r.activity = null;
3620 r.window = null;
3621 r.hideForNow = false;
3622 r.nextIdle = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07003623 // Merge any pending results and pending intents; don't just replace them
3624 if (tmp.pendingResults != null) {
3625 if (r.pendingResults == null) {
3626 r.pendingResults = tmp.pendingResults;
3627 } else {
3628 r.pendingResults.addAll(tmp.pendingResults);
3629 }
3630 }
3631 if (tmp.pendingIntents != null) {
3632 if (r.pendingIntents == null) {
3633 r.pendingIntents = tmp.pendingIntents;
3634 } else {
3635 r.pendingIntents.addAll(tmp.pendingIntents);
3636 }
3637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003638 r.startsNotResumed = tmp.startsNotResumed;
Bob Leee5408332009-09-04 18:31:17 -07003639
Christopher Tateb70f3df2009-04-07 16:07:59 -07003640 handleLaunchActivity(r, currentIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003641 }
3642
Romain Guy65b345f2011-07-27 18:51:50 -07003643 private void handleRequestThumbnail(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003644 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 Bitmap thumbnail = createThumbnailBitmap(r);
3646 CharSequence description = null;
3647 try {
3648 description = r.activity.onCreateDescription();
3649 } catch (Exception e) {
3650 if (!mInstrumentation.onException(r.activity, e)) {
3651 throw new RuntimeException(
3652 "Unable to create description of activity "
3653 + r.intent.getComponent().toShortString()
3654 + ": " + e.toString(), e);
3655 }
3656 }
3657 //System.out.println("Reporting top thumbnail " + thumbnail);
3658 try {
3659 ActivityManagerNative.getDefault().reportThumbnail(
3660 token, thumbnail, description);
3661 } catch (RemoteException ex) {
3662 }
3663 }
3664
Dianne Hackborn73c14162012-09-19 15:45:06 -07003665 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 boolean allActivities, Configuration newConfig) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003667 ArrayList<ComponentCallbacks2> callbacks
3668 = new ArrayList<ComponentCallbacks2>();
Bob Leee5408332009-09-04 18:31:17 -07003669
Dianne Hackborn73c14162012-09-19 15:45:06 -07003670 synchronized (mPackages) {
3671 final int N = mAllApplications.size();
3672 for (int i=0; i<N; i++) {
3673 callbacks.add(mAllApplications.get(i));
3674 }
3675 if (mActivities.size() > 0) {
3676 for (ActivityClientRecord ar : mActivities.values()) {
3677 Activity a = ar.activity;
3678 if (a != null) {
3679 Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
3680 newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
3681 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3682 // If the activity is currently resumed, its configuration
3683 // needs to change right now.
3684 callbacks.add(a);
3685 } else if (thisConfig != null) {
3686 // Otherwise, we will tell it about the change
3687 // the next time it is resumed or shown. Note that
3688 // the activity manager may, before then, decide the
3689 // activity needs to be destroyed to handle its new
3690 // configuration.
3691 if (DEBUG_CONFIGURATION) {
3692 Slog.v(TAG, "Setting activity "
3693 + ar.activityInfo.name + " newConfig=" + thisConfig);
3694 }
3695 ar.newConfig = thisConfig;
Romain Guya998dff2012-03-23 18:58:36 -07003696 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 }
3698 }
3699 }
Dianne Hackborn73c14162012-09-19 15:45:06 -07003700 if (mServices.size() > 0) {
3701 for (Service service : mServices.values()) {
3702 callbacks.add(service);
3703 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 }
3705 }
3706 synchronized (mProviderMap) {
3707 if (mLocalProviders.size() > 0) {
Romain Guya998dff2012-03-23 18:58:36 -07003708 for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
3709 callbacks.add(providerClientRecord.mLocalProvider);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003710 }
3711 }
3712 }
Bob Leee5408332009-09-04 18:31:17 -07003713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003714 return callbacks;
3715 }
Bob Leee5408332009-09-04 18:31:17 -07003716
Romain Guya998dff2012-03-23 18:58:36 -07003717 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 // Only for Activity objects, check that they actually call up to their
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003719 // superclass implementation. ComponentCallbacks2 is an interface, so
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 // we check the runtime type and act accordingly.
3721 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3722 if (activity != null) {
3723 activity.mCalled = false;
3724 }
Bob Leee5408332009-09-04 18:31:17 -07003725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726 boolean shouldChangeConfig = false;
3727 if ((activity == null) || (activity.mCurrentConfig == null)) {
3728 shouldChangeConfig = true;
3729 } else {
Bob Leee5408332009-09-04 18:31:17 -07003730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003731 // If the new config is the same as the config this Activity
3732 // is already running with then don't bother calling
3733 // onConfigurationChanged
3734 int diff = activity.mCurrentConfig.diff(config);
3735 if (diff != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003736 // If this activity doesn't handle any of the config changes
3737 // then don't bother calling onConfigurationChanged as we're
3738 // going to destroy it.
Dianne Hackborne6676352011-06-01 16:51:20 -07003739 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003740 shouldChangeConfig = true;
3741 }
3742 }
3743 }
Bob Leee5408332009-09-04 18:31:17 -07003744
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003745 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003746 + ": shouldChangeConfig=" + shouldChangeConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003747 if (shouldChangeConfig) {
3748 cb.onConfigurationChanged(config);
Bob Leee5408332009-09-04 18:31:17 -07003749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003750 if (activity != null) {
3751 if (!activity.mCalled) {
3752 throw new SuperNotCalledException(
3753 "Activity " + activity.getLocalClassName() +
3754 " did not call through to super.onConfigurationChanged()");
3755 }
3756 activity.mConfigChangeFlags = 0;
3757 activity.mCurrentConfig = new Configuration(config);
3758 }
3759 }
3760 }
3761
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003762 public final void applyConfigurationToResources(Configuration config) {
3763 synchronized (mPackages) {
3764 applyConfigurationToResourcesLocked(config, null);
3765 }
3766 }
3767
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003768 final boolean applyConfigurationToResourcesLocked(Configuration config,
3769 CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003770 if (mResConfiguration == null) {
3771 mResConfiguration = new Configuration();
3772 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003773 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003774 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003775 + mResConfiguration.seq + ", newSeq=" + config.seq);
Dianne Hackbornae078162010-03-18 11:29:37 -07003776 return false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003777 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003778 int changes = mResConfiguration.updateFrom(config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003779 flushDisplayMetricsLocked();
3780 DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
3781 Display.DEFAULT_DISPLAY, null);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003782
3783 if (compat != null && (mResCompatibilityInfo == null ||
3784 !mResCompatibilityInfo.equals(compat))) {
3785 mResCompatibilityInfo = compat;
3786 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
3787 | ActivityInfo.CONFIG_SCREEN_SIZE
3788 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
3789 }
Bob Leee5408332009-09-04 18:31:17 -07003790
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003791 // set it for java, this also affects newly created Resources
3792 if (config.locale != null) {
3793 Locale.setDefault(config.locale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003794 }
Bob Leee5408332009-09-04 18:31:17 -07003795
Jeff Browna492c3a2012-08-23 19:48:44 -07003796 Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
Bob Leee5408332009-09-04 18:31:17 -07003797
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08003798 ApplicationPackageManager.configurationChanged();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003799 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
Dianne Hackborn756220b2012-08-14 16:45:30 -07003800
3801 Configuration tmpConfig = null;
3802
3803 Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
3804 mActiveResources.entrySet().iterator();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003805 while (it.hasNext()) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07003806 Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
3807 Resources r = entry.getValue().get();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003808 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003809 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003810 + r + " config to: " + config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003811 int displayId = entry.getKey().mDisplayId;
3812 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
3813 DisplayMetrics dm = defaultDisplayMetrics;
3814 Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
3815 if (!isDefaultDisplay || overrideConfig != null) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07003816 if (tmpConfig == null) {
3817 tmpConfig = new Configuration();
3818 }
3819 tmpConfig.setTo(config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003820 if (!isDefaultDisplay) {
3821 dm = getDisplayMetricsLocked(displayId, null);
3822 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
3823 }
3824 if (overrideConfig != null) {
3825 tmpConfig.updateFrom(overrideConfig);
3826 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07003827 r.updateConfiguration(tmpConfig, dm, compat);
3828 } else {
3829 r.updateConfiguration(config, dm, compat);
3830 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003831 //Slog.i(TAG, "Updated app resources " + v.getKey()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003832 // + " " + r + ": " + r.getConfiguration());
3833 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003834 //Slog.i(TAG, "Removing old resources " + v.getKey());
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003835 it.remove();
3836 }
3837 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003838
3839 return changes != 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003840 }
Dianne Hackborn836e2622011-10-04 18:32:39 -07003841
Jeff Browna492c3a2012-08-23 19:48:44 -07003842 final void applyNonDefaultDisplayMetricsToConfigurationLocked(
3843 DisplayMetrics dm, Configuration config) {
3844 config.screenLayout = Configuration.SCREENLAYOUT_SIZE_XLARGE
3845 | Configuration.SCREENLAYOUT_LONG_NO;
3846 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
3847 config.orientation = (dm.widthPixels >= dm.heightPixels) ?
3848 Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
3849 config.densityDpi = dm.densityDpi;
3850 config.screenWidthDp = (int)(dm.widthPixels / dm.density);
3851 config.screenHeightDp = (int)(dm.heightPixels / dm.density);
3852 config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
3853 config.compatScreenWidthDp = config.screenWidthDp;
3854 config.compatScreenHeightDp = config.screenHeightDp;
3855 config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
3856 }
3857
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003858 final Configuration applyCompatConfiguration(int displayDensity) {
Dianne Hackborn836e2622011-10-04 18:32:39 -07003859 Configuration config = mConfiguration;
3860 if (mCompatConfiguration == null) {
3861 mCompatConfiguration = new Configuration();
3862 }
3863 mCompatConfiguration.setTo(mConfiguration);
3864 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003865 mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration);
Dianne Hackborn836e2622011-10-04 18:32:39 -07003866 config = mCompatConfiguration;
3867 }
3868 return config;
3869 }
3870
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003871 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003872
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003873 int configDiff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003874
3875 synchronized (mPackages) {
3876 if (mPendingConfiguration != null) {
3877 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3878 config = mPendingConfiguration;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003879 mCurDefaultDisplayDpi = config.densityDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -07003880 updateDefaultDensity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003881 }
3882 mPendingConfiguration = null;
3883 }
3884
3885 if (config == null) {
3886 return;
3887 }
3888
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003889 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003890 + config);
3891
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003892 applyConfigurationToResourcesLocked(config, compat);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003894 if (mConfiguration == null) {
3895 mConfiguration = new Configuration();
3896 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003897 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003898 return;
3899 }
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003900 configDiff = mConfiguration.diff(config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003901 mConfiguration.updateFrom(config);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003902 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003903 }
Dianne Hackborn73c14162012-09-19 15:45:06 -07003904
3905 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
3906
Romain Guy65b345f2011-07-27 18:51:50 -07003907 // Cleanup hardware accelerated stuff
Jeff Brown98365d72012-08-19 20:30:52 -07003908 WindowManagerGlobal.getInstance().trimLocalMemory();
Bob Leee5408332009-09-04 18:31:17 -07003909
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003910 freeTextLayoutCachesIfNeeded(configDiff);
3911
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003912 if (callbacks != null) {
3913 final int N = callbacks.size();
3914 for (int i=0; i<N; i++) {
3915 performConfigurationChanged(callbacks.get(i), config);
3916 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003917 }
3918 }
3919
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003920 final void freeTextLayoutCachesIfNeeded(int configDiff) {
3921 if (configDiff != 0) {
3922 // Ask text layout engine to free its caches if there is a locale change
3923 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
3924 if (hasLocaleConfigChange) {
3925 Canvas.freeTextLayoutCaches();
3926 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
3927 }
3928 }
3929 }
3930
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003931 final void handleActivityConfigurationChanged(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003932 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003933 if (r == null || r.activity == null) {
3934 return;
3935 }
Bob Leee5408332009-09-04 18:31:17 -07003936
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003937 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003938 + r.activityInfo.name);
3939
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003940 performConfigurationChanged(r.activity, mCompatConfiguration);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003941
3942 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003943 }
3944
Romain Guy7eabe552011-07-21 14:56:34 -07003945 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003946 if (start) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003947 try {
Romain Guy7eabe552011-07-21 14:56:34 -07003948 switch (profileType) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07003949 default:
3950 mProfiler.setProfiler(pcd.path, pcd.fd);
3951 mProfiler.autoStopProfiler = false;
3952 mProfiler.startProfiling();
Romain Guy7eabe552011-07-21 14:56:34 -07003953 break;
3954 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003955 } catch (RuntimeException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003956 Slog.w(TAG, "Profiling failed on path " + pcd.path
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003957 + " -- can the process access this path?");
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003958 } finally {
3959 try {
3960 pcd.fd.close();
3961 } catch (IOException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003962 Slog.w(TAG, "Failure closing profile fd", e);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003963 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003964 }
3965 } else {
Romain Guy7eabe552011-07-21 14:56:34 -07003966 switch (profileType) {
Romain Guy7eabe552011-07-21 14:56:34 -07003967 default:
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07003968 mProfiler.stopProfiling();
Romain Guy7eabe552011-07-21 14:56:34 -07003969 break;
Romain Guy7eabe552011-07-21 14:56:34 -07003970 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003971 }
3972 }
Bob Leee5408332009-09-04 18:31:17 -07003973
Romain Guya998dff2012-03-23 18:58:36 -07003974 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
Andy McFadden824c5102010-07-09 16:26:57 -07003975 if (managed) {
3976 try {
3977 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
3978 } catch (IOException e) {
3979 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
3980 + " -- can the process access this path?");
3981 } finally {
3982 try {
3983 dhd.fd.close();
3984 } catch (IOException e) {
3985 Slog.w(TAG, "Failure closing profile fd", e);
3986 }
3987 }
3988 } else {
Andy McFadden06a6b552010-07-13 16:28:09 -07003989 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
Andy McFadden824c5102010-07-09 16:26:57 -07003990 }
3991 }
3992
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003993 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
3994 boolean hasPkgInfo = false;
3995 if (packages != null) {
3996 for (int i=packages.length-1; i>=0; i--) {
3997 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
3998 if (!hasPkgInfo) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003999 WeakReference<LoadedApk> ref;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07004000 ref = mPackages.get(packages[i]);
4001 if (ref != null && ref.get() != null) {
4002 hasPkgInfo = true;
4003 } else {
4004 ref = mResourcePackages.get(packages[i]);
4005 if (ref != null && ref.get() != null) {
4006 hasPkgInfo = true;
4007 }
4008 }
4009 }
4010 mPackages.remove(packages[i]);
4011 mResourcePackages.remove(packages[i]);
4012 }
4013 }
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08004014 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07004015 hasPkgInfo);
4016 }
4017
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004018 final void handleLowMemory() {
Dianne Hackborn73c14162012-09-19 15:45:06 -07004019 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
Bob Leee5408332009-09-04 18:31:17 -07004020
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004021 final int N = callbacks.size();
4022 for (int i=0; i<N; i++) {
4023 callbacks.get(i).onLowMemory();
4024 }
4025
Chris Tatece229052009-03-25 16:44:52 -07004026 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4027 if (Process.myUid() != Process.SYSTEM_UID) {
4028 int sqliteReleased = SQLiteDatabase.releaseMemory();
4029 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4030 }
Bob Leee5408332009-09-04 18:31:17 -07004031
Mike Reedcaf0df12009-04-27 14:32:05 -04004032 // Ask graphics to free up as much as possible (font/image caches)
4033 Canvas.freeCaches();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004034
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07004035 // Ask text layout engine to free also as much as possible
4036 Canvas.freeTextLayoutCaches();
4037
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004038 BinderInternal.forceGc("mem");
4039 }
4040
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004041 final void handleTrimMemory(int level) {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07004042 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004043
Jeff Brown98365d72012-08-19 20:30:52 -07004044 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
Romain Guy19f86e82012-04-23 15:19:07 -07004045 windowManager.startTrimMemory(level);
4046
Dianne Hackborn73c14162012-09-19 15:45:06 -07004047 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004048
4049 final int N = callbacks.size();
Romain Guya998dff2012-03-23 18:58:36 -07004050 for (int i = 0; i < N; i++) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004051 callbacks.get(i).onTrimMemory(level);
4052 }
Romain Guy19f86e82012-04-23 15:19:07 -07004053
Jeff Brown98365d72012-08-19 20:30:52 -07004054 windowManager.endTrimMemory();
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004055 }
4056
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004057 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004058 if (Process.isIsolated()) {
4059 // Isolated processes aren't going to do UI.
4060 return;
4061 }
Romain Guya9582652011-11-10 14:20:10 -08004062 try {
4063 int uid = Process.myUid();
4064 String[] packages = getPackageManager().getPackagesForUid(uid);
4065
4066 // If there are several packages in this application we won't
4067 // initialize the graphics disk caches
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004068 if (packages != null && packages.length == 1) {
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004069 HardwareRenderer.setupDiskCache(cacheDir);
4070 RenderScript.setupDiskCache(cacheDir);
Romain Guya9582652011-11-10 14:20:10 -08004071 }
4072 } catch (RemoteException e) {
4073 // Ignore
4074 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07004075 }
4076
4077 private void updateDefaultDensity() {
4078 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4079 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4080 && !mDensityCompatMode) {
4081 Slog.i(TAG, "Switching default density from "
4082 + DisplayMetrics.DENSITY_DEVICE + " to "
4083 + mCurDefaultDisplayDpi);
4084 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4085 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4086 }
4087 }
4088
Romain Guy65b345f2011-07-27 18:51:50 -07004089 private void handleBindApplication(AppBindData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004090 mBoundApplication = data;
4091 mConfiguration = new Configuration(data.config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07004092 mCompatConfiguration = new Configuration(data.config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004093
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004094 mProfiler = new Profiler();
4095 mProfiler.profileFile = data.initProfileFile;
4096 mProfiler.profileFd = data.initProfileFd;
4097 mProfiler.autoStopProfiler = data.initAutoStopProfiler;
4098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004099 // send up app name; do this *before* waiting for debugger
Christopher Tate8ee038d2009-11-06 11:30:20 -08004100 Process.setArgV0(data.processName);
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004101 android.ddm.DdmHandleAppName.setAppName(data.processName,
4102 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004103
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004104 if (data.persistent) {
4105 // Persistent processes on low-memory devices do not get to
4106 // use hardware accelerated drawing, since this can add too much
4107 // overhead to the process.
Jeff Brown98365d72012-08-19 20:30:52 -07004108 if (!ActivityManager.isHighEndGfx()) {
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004109 HardwareRenderer.disable(false);
4110 }
4111 }
Romain Guya9582652011-11-10 14:20:10 -08004112
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004113 if (mProfiler.profileFd != null) {
4114 mProfiler.startProfiling();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004115 }
4116
Joe Onoratod630f102011-03-17 18:42:26 -07004117 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4118 // implementation to use the pool executor. Normally, we use the
4119 // serialized executor as the default. This has to happen in the
4120 // main thread so the main looper is set right.
Dianne Hackborn81e92762011-10-09 16:00:21 -07004121 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
Joe Onoratod630f102011-03-17 18:42:26 -07004122 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4123 }
4124
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004125 /*
4126 * Before spawning a new process, reset the time zone to be the system time zone.
4127 * This needs to be done because the system time zone could have changed after the
4128 * the spawning of this process. Without doing this this process would have the incorrect
4129 * system time zone.
4130 */
4131 TimeZone.setDefault(null);
4132
4133 /*
4134 * Initialize the default locale in this process for the reasons we set the time zone.
4135 */
4136 Locale.setDefault(data.config.locale);
4137
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07004138 /*
4139 * Update the system configuration since its preloaded and might not
4140 * reflect configuration changes. The configuration object passed
4141 * in AppBindData can be safely assumed to be up to date
4142 */
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004143 applyConfigurationToResourcesLocked(data.config, data.compatInfo);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07004144 mCurDefaultDisplayDpi = data.config.densityDpi;
4145 applyCompatConfiguration(mCurDefaultDisplayDpi);
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07004146
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004147 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004148
Dianne Hackborndde331c2012-08-03 14:01:57 -07004149 /**
4150 * Switch this process to density compatibility mode if needed.
4151 */
4152 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4153 == 0) {
4154 mDensityCompatMode = true;
4155 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4156 }
4157 updateDefaultDensity();
4158
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004159 final ContextImpl appContext = new ContextImpl();
4160 appContext.init(data.info, null, this);
Amith Yamasani11de39a2012-08-17 18:00:52 -07004161 if (!Process.isIsolated()) {
4162 final File cacheDir = appContext.getCacheDir();
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004163
Amith Yamasani92d57052012-08-23 10:07:52 -07004164 if (cacheDir != null) {
4165 // Provide a usable directory for temporary files
4166 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4167
4168 setupGraphicsSupport(data.info, cacheDir);
4169 } else {
4170 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4171 }
Amith Yamasani11de39a2012-08-17 18:00:52 -07004172 }
Dianne Hackborn96e240f2009-07-26 17:42:30 -07004173 /**
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07004174 * For system applications on userdebug/eng builds, log stack
4175 * traces of disk and network access to dropbox for analysis.
4176 */
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07004177 if ((data.appInfo.flags &
4178 (ApplicationInfo.FLAG_SYSTEM |
Brad Fitzpatrick50d66f92010-09-13 21:29:05 -07004179 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4180 StrictMode.conditionallyEnableDebugLogging();
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07004181 }
4182
4183 /**
Brad Fitzpatrickb6e18412010-10-28 14:50:05 -07004184 * For apps targetting SDK Honeycomb or later, we don't allow
4185 * network usage on the main event loop / UI thread.
4186 *
4187 * Note to those grepping: this is what ultimately throws
4188 * NetworkOnMainThreadException ...
4189 */
4190 if (data.appInfo.targetSdkVersion > 9) {
4191 StrictMode.enableDeathOnNetwork();
4192 }
4193
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004194 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4195 // XXX should have option to change the port.
4196 Debug.changeDebugPort(8100);
4197 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004198 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004199 + " is waiting for the debugger on port 8100...");
4200
4201 IActivityManager mgr = ActivityManagerNative.getDefault();
4202 try {
4203 mgr.showWaitingForDebugger(mAppThread, true);
4204 } catch (RemoteException ex) {
4205 }
4206
4207 Debug.waitForDebugger();
4208
4209 try {
4210 mgr.showWaitingForDebugger(mAppThread, false);
4211 } catch (RemoteException ex) {
4212 }
4213
4214 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004215 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004216 + " can be debugged on port 8100...");
4217 }
4218 }
4219
Siva Velusamy92a8b222012-03-09 16:24:04 -08004220 // Enable OpenGL tracing if required
4221 if (data.enableOpenGlTrace) {
4222 GLUtils.enableTracing();
4223 }
4224
Robert Greenwalt434203a2010-10-11 16:00:27 -07004225 /**
4226 * Initialize the default http proxy in this process for the reasons we set the time zone.
4227 */
4228 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
Dianne Hackbornd4d32c52011-11-08 17:33:59 -08004229 if (b != null) {
4230 // In pre-boot mode (doing initial launch to collect password), not
4231 // all system is up. This includes the connectivity service, so don't
4232 // crash if we can't get it.
4233 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4234 try {
4235 ProxyProperties proxyProperties = service.getProxy();
4236 Proxy.setHttpProxySystemProperty(proxyProperties);
4237 } catch (RemoteException e) {}
4238 }
Robert Greenwalt434203a2010-10-11 16:00:27 -07004239
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004240 if (data.instrumentationName != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004241 InstrumentationInfo ii = null;
4242 try {
4243 ii = appContext.getPackageManager().
4244 getInstrumentationInfo(data.instrumentationName, 0);
4245 } catch (PackageManager.NameNotFoundException e) {
4246 }
4247 if (ii == null) {
4248 throw new RuntimeException(
4249 "Unable to find instrumentation info for: "
4250 + data.instrumentationName);
4251 }
4252
4253 mInstrumentationAppDir = ii.sourceDir;
Brian Carlstromd893a892012-04-01 21:30:26 -07004254 mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004255 mInstrumentationAppPackage = ii.packageName;
4256 mInstrumentedAppDir = data.info.getAppDir();
Brian Carlstromd893a892012-04-01 21:30:26 -07004257 mInstrumentedAppLibraryDir = data.info.getLibDir();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004258
4259 ApplicationInfo instrApp = new ApplicationInfo();
4260 instrApp.packageName = ii.packageName;
4261 instrApp.sourceDir = ii.sourceDir;
4262 instrApp.publicSourceDir = ii.publicSourceDir;
4263 instrApp.dataDir = ii.dataDir;
Kenny Root85387d72010-08-26 10:13:11 -07004264 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004265 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004266 appContext.getClassLoader(), false, true);
Dianne Hackborn21556372010-02-04 16:34:40 -08004267 ContextImpl instrContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004268 instrContext.init(pi, null, this);
4269
4270 try {
4271 java.lang.ClassLoader cl = instrContext.getClassLoader();
4272 mInstrumentation = (Instrumentation)
4273 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4274 } catch (Exception e) {
4275 throw new RuntimeException(
4276 "Unable to instantiate instrumentation "
4277 + data.instrumentationName + ": " + e.toString(), e);
4278 }
4279
4280 mInstrumentation.init(this, instrContext, appContext,
4281 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
4282
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004283 if (mProfiler.profileFile != null && !ii.handleProfiling
4284 && mProfiler.profileFd == null) {
4285 mProfiler.handlingProfiling = true;
4286 File file = new File(mProfiler.profileFile);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004287 file.getParentFile().mkdirs();
4288 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4289 }
4290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004291 } else {
4292 mInstrumentation = new Instrumentation();
4293 }
4294
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08004295 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
Dianne Hackbornde398512011-01-18 18:45:21 -08004296 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08004297 }
4298
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004299 // Allow disk access during application and provider setup. This could
Jeff Sharkey7c501672012-02-28 12:08:37 -08004300 // block processing ordered broadcasts, but later processing would
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004301 // probably end up doing the same disk access.
Jeff Sharkey7c501672012-02-28 12:08:37 -08004302 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004303 try {
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004304 // If the app is being launched for full backup or restore, bring it up in
4305 // a restricted environment with the base application class.
4306 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4307 mInitialApplication = app;
Jeff Sharkey7c501672012-02-28 12:08:37 -08004308
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004309 // don't bring up providers in restricted mode; they may depend on the
4310 // app's custom Application class
4311 if (!data.restrictedBackupMode) {
4312 List<ProviderInfo> providers = data.providers;
4313 if (providers != null) {
4314 installContentProviders(app, providers);
4315 // For process that contains content providers, we want to
4316 // ensure that the JIT is enabled "at some point".
4317 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4318 }
4319 }
4320
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004321 // Do this after providers, since instrumentation tests generally start their
4322 // test thread at this point, and we don't want that racing.
4323 try {
4324 mInstrumentation.onCreate(data.instrumentationArgs);
4325 }
4326 catch (Exception e) {
4327 throw new RuntimeException(
4328 "Exception thrown in onCreate() of "
4329 + data.instrumentationName + ": " + e.toString(), e);
4330 }
4331
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004332 try {
4333 mInstrumentation.callApplicationOnCreate(app);
4334 } catch (Exception e) {
4335 if (!mInstrumentation.onException(app, e)) {
4336 throw new RuntimeException(
4337 "Unable to create application " + app.getClass().getName()
4338 + ": " + e.toString(), e);
4339 }
4340 }
4341 } finally {
4342 StrictMode.setThreadPolicy(savedPolicy);
4343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004344 }
4345
4346 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4347 IActivityManager am = ActivityManagerNative.getDefault();
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004348 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4349 && mProfiler.profileFd == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004350 Debug.stopMethodTracing();
4351 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004352 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 // + ", app thr: " + mAppThread);
4354 try {
4355 am.finishInstrumentation(mAppThread, resultCode, results);
4356 } catch (RemoteException ex) {
4357 }
4358 }
4359
Romain Guy65b345f2011-07-27 18:51:50 -07004360 private void installContentProviders(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004361 Context context, List<ProviderInfo> providers) {
4362 final ArrayList<IActivityManager.ContentProviderHolder> results =
4363 new ArrayList<IActivityManager.ContentProviderHolder>();
4364
Romain Guya998dff2012-03-23 18:58:36 -07004365 for (ProviderInfo cpi : providers) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004366 StringBuilder buf = new StringBuilder(128);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07004367 buf.append("Pub ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004368 buf.append(cpi.authority);
4369 buf.append(": ");
4370 buf.append(cpi.name);
4371 Log.i(TAG, buf.toString());
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004372 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4373 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4374 if (cph != null) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004375 cph.noReleaseNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004376 results.add(cph);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004377 }
4378 }
4379
4380 try {
4381 ActivityManagerNative.getDefault().publishContentProviders(
4382 getApplicationThread(), results);
4383 } catch (RemoteException ex) {
4384 }
4385 }
4386
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004387 public final IContentProvider acquireProvider(Context c, String name, boolean stable) {
4388 IContentProvider provider = acquireExistingProvider(c, name, stable);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004389 if (provider != null) {
4390 return provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004391 }
4392
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004393 // There is a possible race here. Another thread may try to acquire
4394 // the same provider at the same time. When this happens, we want to ensure
4395 // that the first one wins.
4396 // Note that we cannot hold the lock while acquiring and installing the
4397 // provider since it might take a long time to run and it could also potentially
4398 // be re-entrant in the case where the provider is in the same process.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 IActivityManager.ContentProviderHolder holder = null;
4400 try {
4401 holder = ActivityManagerNative.getDefault().getContentProvider(
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004402 getApplicationThread(), name, stable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004403 } catch (RemoteException ex) {
4404 }
4405 if (holder == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004406 Slog.e(TAG, "Failed to find provider info for " + name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004407 return null;
4408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004409
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004410 // Install provider will increment the reference count for us, and break
4411 // any ties in the race.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004412 holder = installProvider(c, holder, holder.info,
4413 true /*noisy*/, holder.noReleaseNeeded, stable);
4414 return holder.provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004415 }
4416
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004417 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4418 if (stable) {
4419 prc.stableCount += 1;
4420 if (prc.stableCount == 1) {
4421 // We are acquiring a new stable reference on the provider.
4422 int unstableDelta;
4423 if (prc.removePending) {
4424 // We have a pending remove operation, which is holding the
4425 // last unstable reference. At this point we are converting
4426 // that unstable reference to our new stable reference.
4427 unstableDelta = -1;
4428 // Cancel the removal of the provider.
4429 if (DEBUG_PROVIDER) {
4430 Slog.v(TAG, "incProviderRef: stable "
4431 + "snatched provider from the jaws of death");
4432 }
4433 prc.removePending = false;
4434 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4435 } else {
4436 unstableDelta = 0;
4437 }
4438 try {
4439 if (DEBUG_PROVIDER) {
4440 Slog.v(TAG, "incProviderRef Now stable - "
4441 + prc.holder.info.name + ": unstableDelta="
4442 + unstableDelta);
4443 }
4444 ActivityManagerNative.getDefault().refContentProvider(
4445 prc.holder.connection, 1, unstableDelta);
4446 } catch (RemoteException e) {
4447 //do nothing content provider object is dead any way
4448 }
4449 }
4450 } else {
4451 prc.unstableCount += 1;
4452 if (prc.unstableCount == 1) {
4453 // We are acquiring a new unstable reference on the provider.
4454 if (prc.removePending) {
4455 // Oh look, we actually have a remove pending for the
4456 // provider, which is still holding the last unstable
4457 // reference. We just need to cancel that to take new
4458 // ownership of the reference.
4459 if (DEBUG_PROVIDER) {
4460 Slog.v(TAG, "incProviderRef: unstable "
4461 + "snatched provider from the jaws of death");
4462 }
4463 prc.removePending = false;
4464 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4465 } else {
4466 // First unstable ref, increment our count in the
4467 // activity manager.
4468 try {
4469 if (DEBUG_PROVIDER) {
4470 Slog.v(TAG, "incProviderRef: Now unstable - "
4471 + prc.holder.info.name);
4472 }
4473 ActivityManagerNative.getDefault().refContentProvider(
4474 prc.holder.connection, 0, 1);
4475 } catch (RemoteException e) {
4476 //do nothing content provider object is dead any way
4477 }
4478 }
4479 }
4480 }
4481 }
4482
4483 public final IContentProvider acquireExistingProvider(Context c, String name,
4484 boolean stable) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004485 synchronized (mProviderMap) {
4486 ProviderClientRecord pr = mProviderMap.get(name);
4487 if (pr == null) {
4488 return null;
4489 }
4490
4491 IContentProvider provider = pr.mProvider;
4492 IBinder jBinder = provider.asBinder();
4493
4494 // Only increment the ref count if we have one. If we don't then the
4495 // provider is not reference counted and never needs to be released.
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07004496 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004497 if (prc != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004498 incProviderRefLocked(prc, stable);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004499 }
4500 return provider;
4501 }
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07004502 }
4503
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004504 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4505 if (provider == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004506 return false;
4507 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004508
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004509 IBinder jBinder = provider.asBinder();
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004510 synchronized (mProviderMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004511 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004512 if (prc == null) {
4513 // The provider has no ref count, no release is needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004514 return false;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004515 }
4516
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004517 boolean lastRef = false;
4518 if (stable) {
4519 if (prc.stableCount == 0) {
4520 if (DEBUG_PROVIDER) Slog.v(TAG,
4521 "releaseProvider: stable ref count already 0, how?");
4522 return false;
4523 }
4524 prc.stableCount -= 1;
4525 if (prc.stableCount == 0) {
4526 // What we do at this point depends on whether there are
4527 // any unstable refs left: if there are, we just tell the
4528 // activity manager to decrement its stable count; if there
4529 // aren't, we need to enqueue this provider to be removed,
4530 // and convert to holding a single unstable ref while
4531 // doing so.
4532 lastRef = prc.unstableCount == 0;
4533 try {
4534 if (DEBUG_PROVIDER) {
4535 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4536 + lastRef + " - " + prc.holder.info.name);
4537 }
4538 ActivityManagerNative.getDefault().refContentProvider(
4539 prc.holder.connection, -1, lastRef ? 1 : 0);
4540 } catch (RemoteException e) {
4541 //do nothing content provider object is dead any way
4542 }
4543 }
4544 } else {
4545 if (prc.unstableCount == 0) {
4546 if (DEBUG_PROVIDER) Slog.v(TAG,
4547 "releaseProvider: unstable ref count already 0, how?");
4548 return false;
4549 }
4550 prc.unstableCount -= 1;
4551 if (prc.unstableCount == 0) {
4552 // If this is the last reference, we need to enqueue
4553 // this provider to be removed instead of telling the
4554 // activity manager to remove it at this point.
4555 lastRef = prc.stableCount == 0;
4556 if (!lastRef) {
4557 try {
4558 if (DEBUG_PROVIDER) {
4559 Slog.v(TAG, "releaseProvider: No longer unstable - "
4560 + prc.holder.info.name);
4561 }
4562 ActivityManagerNative.getDefault().refContentProvider(
4563 prc.holder.connection, 0, -1);
4564 } catch (RemoteException e) {
4565 //do nothing content provider object is dead any way
4566 }
4567 }
4568 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004569 }
4570
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004571 if (lastRef) {
4572 if (!prc.removePending) {
4573 // Schedule the actual remove asynchronously, since we don't know the context
4574 // this will be called in.
4575 // TODO: it would be nice to post a delayed message, so
4576 // if we come back and need the same provider quickly
4577 // we will still have it available.
4578 if (DEBUG_PROVIDER) {
4579 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4580 + prc.holder.info.name);
4581 }
4582 prc.removePending = true;
4583 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4584 mH.sendMessage(msg);
4585 } else {
4586 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4587 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004588 }
4589 return true;
4590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004591 }
4592
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004593 final void completeRemoveProvider(ProviderRefCount prc) {
4594 synchronized (mProviderMap) {
4595 if (!prc.removePending) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004596 // There was a race! Some other client managed to acquire
4597 // the provider before the removal was completed.
4598 // Abort the removal. We will do it later.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004599 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004600 + "provider still in use");
4601 return;
4602 }
4603
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004604 final IBinder jBinder = prc.holder.provider.asBinder();
4605 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4606 if (existingPrc == prc) {
4607 mProviderRefCountMap.remove(jBinder);
4608 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004609
4610 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
4611 while (iter.hasNext()) {
4612 ProviderClientRecord pr = iter.next();
4613 IBinder myBinder = pr.mProvider.asBinder();
4614 if (myBinder == jBinder) {
4615 iter.remove();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004616 }
4617 }
4618 }
4619
4620 try {
4621 if (DEBUG_PROVIDER) {
4622 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4623 + "removeContentProvider(" + prc.holder.info.name + ")");
4624 }
4625 ActivityManagerNative.getDefault().removeContentProvider(
4626 prc.holder.connection, false);
4627 } catch (RemoteException e) {
4628 //do nothing content provider object is dead any way
4629 }
4630 }
4631
4632 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
4633 synchronized(mProviderMap) {
4634 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4635 if (prc != null) {
4636 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4637 + provider + " " + prc.holder.info.name);
4638 mProviderRefCountMap.remove(provider);
4639 if (prc.client != null && prc.client.mNames != null) {
4640 for (String name : prc.client.mNames) {
4641 ProviderClientRecord pr = mProviderMap.get(name);
4642 if (pr != null && pr.mProvider.asBinder() == provider) {
4643 Slog.i(TAG, "Removing dead content provider: " + name);
4644 mProviderMap.remove(name);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004645 }
4646 }
4647 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004648 if (fromClient) {
4649 // We found out about this due to execution in our client
4650 // code. Tell the activity manager about it now, to ensure
4651 // that the next time we go to do anything with the provider
4652 // it knows it is dead (so we don't race with its death
4653 // notification).
4654 try {
4655 ActivityManagerNative.getDefault().unstableProviderDied(
4656 prc.holder.connection);
4657 } catch (RemoteException e) {
4658 //do nothing content provider object is dead any way
4659 }
4660 }
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004661 }
4662 }
4663 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004664
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004665 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4666 ContentProvider localProvider,IActivityManager.ContentProviderHolder holder) {
4667 String names[] = PATTERN_SEMICOLON.split(holder.info.authority);
4668 ProviderClientRecord pcr = new ProviderClientRecord(names, provider,
4669 localProvider, holder);
4670 for (int i = 0; i < names.length; i++) {
4671 ProviderClientRecord existing = mProviderMap.get(names[i]);
4672 if (existing != null) {
4673 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
4674 + " already published as " + names[i]);
4675 } else {
4676 mProviderMap.put(names[i], pcr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004677 }
4678 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004679 return pcr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004680 }
4681
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004682 /**
4683 * Installs the provider.
4684 *
4685 * Providers that are local to the process or that come from the system server
4686 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4687 * Other remote providers are reference counted. The initial reference count
4688 * for all reference counted providers is one. Providers that are not reference
4689 * counted do not have a reference count (at all).
4690 *
4691 * This method detects when a provider has already been installed. When this happens,
4692 * it increments the reference count of the existing provider (if appropriate)
4693 * and returns the existing provider. This can happen due to concurrent
4694 * attempts to acquire the same provider.
4695 */
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004696 private IActivityManager.ContentProviderHolder installProvider(Context context,
4697 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4698 boolean noisy, boolean noReleaseNeeded, boolean stable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004699 ContentProvider localProvider = null;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004700 IContentProvider provider;
Dianne Hackborn5f48fca2012-05-30 11:06:31 -07004701 if (holder == null || holder.provider == null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004702 if (DEBUG_PROVIDER || noisy) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004703 Slog.d(TAG, "Loading provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004704 + info.name);
4705 }
4706 Context c = null;
4707 ApplicationInfo ai = info.applicationInfo;
4708 if (context.getPackageName().equals(ai.packageName)) {
4709 c = context;
4710 } else if (mInitialApplication != null &&
4711 mInitialApplication.getPackageName().equals(ai.packageName)) {
4712 c = mInitialApplication;
4713 } else {
4714 try {
4715 c = context.createPackageContext(ai.packageName,
4716 Context.CONTEXT_INCLUDE_CODE);
4717 } catch (PackageManager.NameNotFoundException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07004718 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004719 }
4720 }
4721 if (c == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004722 Slog.w(TAG, "Unable to get context for package " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004723 ai.packageName +
4724 " while loading content provider " +
4725 info.name);
4726 return null;
4727 }
4728 try {
4729 final java.lang.ClassLoader cl = c.getClassLoader();
4730 localProvider = (ContentProvider)cl.
4731 loadClass(info.name).newInstance();
4732 provider = localProvider.getIContentProvider();
4733 if (provider == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004734 Slog.e(TAG, "Failed to instantiate class " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004735 info.name + " from sourceDir " +
4736 info.applicationInfo.sourceDir);
4737 return null;
4738 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004739 if (DEBUG_PROVIDER) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004740 TAG, "Instantiating local provider " + info.name);
4741 // XXX Need to create the correct context for this provider.
4742 localProvider.attachInfo(c, info);
4743 } catch (java.lang.Exception e) {
4744 if (!mInstrumentation.onException(null, e)) {
4745 throw new RuntimeException(
4746 "Unable to get provider " + info.name
4747 + ": " + e.toString(), e);
4748 }
4749 return null;
4750 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004751 } else {
4752 provider = holder.provider;
4753 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 + info.name);
4755 }
4756
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004757 IActivityManager.ContentProviderHolder retHolder;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004758
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004759 synchronized (mProviderMap) {
4760 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4761 + " / " + info.name);
4762 IBinder jBinder = provider.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004763 if (localProvider != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004764 ComponentName cname = new ComponentName(info.packageName, info.name);
4765 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004766 if (pr != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004767 if (DEBUG_PROVIDER) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004768 Slog.v(TAG, "installProvider: lost the race, "
4769 + "using existing local provider");
4770 }
4771 provider = pr.mProvider;
4772 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004773 holder = new IActivityManager.ContentProviderHolder(info);
4774 holder.provider = provider;
4775 holder.noReleaseNeeded = true;
4776 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004777 mLocalProviders.put(jBinder, pr);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004778 mLocalProvidersByName.put(cname, pr);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004779 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004780 retHolder = pr.mHolder;
4781 } else {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004782 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4783 if (prc != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004784 if (DEBUG_PROVIDER) {
4785 Slog.v(TAG, "installProvider: lost the race, updating ref count");
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004786 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004787 // We need to transfer our new reference to the existing
4788 // ref count, releasing the old one... but only if
4789 // release is needed (that is, it is not running in the
4790 // system process).
4791 if (!noReleaseNeeded) {
4792 incProviderRefLocked(prc, stable);
4793 try {
4794 ActivityManagerNative.getDefault().removeContentProvider(
4795 holder.connection, stable);
4796 } catch (RemoteException e) {
4797 //do nothing content provider object is dead any way
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004798 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004799 }
4800 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004801 ProviderClientRecord client = installProviderAuthoritiesLocked(
4802 provider, localProvider, holder);
4803 if (noReleaseNeeded) {
4804 prc = new ProviderRefCount(holder, client, 1000, 1000);
4805 } else {
4806 prc = stable
4807 ? new ProviderRefCount(holder, client, 1, 0)
4808 : new ProviderRefCount(holder, client, 0, 1);
4809 }
4810 mProviderRefCountMap.put(jBinder, prc);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004811 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004812 retHolder = prc.holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004813 }
4814 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004815
4816 return retHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004817 }
4818
Romain Guy65b345f2011-07-27 18:51:50 -07004819 private void attach(boolean system) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004820 sThreadLocal.set(this);
4821 mSystemThread = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004822 if (!system) {
Dianne Hackborn6dd005b2011-07-18 13:22:50 -07004823 ViewRootImpl.addFirstDrawHandler(new Runnable() {
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08004824 public void run() {
4825 ensureJitEnabled();
4826 }
4827 });
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004828 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
4829 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004830 RuntimeInit.setApplicationObject(mAppThread.asBinder());
4831 IActivityManager mgr = ActivityManagerNative.getDefault();
4832 try {
4833 mgr.attachApplication(mAppThread);
4834 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07004835 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004836 }
4837 } else {
4838 // Don't set application object here -- if the system crashes,
4839 // we can't display an alert, we just want to die die die.
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004840 android.ddm.DdmHandleAppName.setAppName("system_process",
4841 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004842 try {
4843 mInstrumentation = new Instrumentation();
Dianne Hackborn21556372010-02-04 16:34:40 -08004844 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004845 context.init(getSystemContext().mPackageInfo, null, this);
4846 Application app = Instrumentation.newApplication(Application.class, context);
4847 mAllApplications.add(app);
4848 mInitialApplication = app;
4849 app.onCreate();
4850 } catch (Exception e) {
4851 throw new RuntimeException(
4852 "Unable to instantiate Application():" + e.toString(), e);
4853 }
4854 }
Geremy Condrab7faaf42012-09-19 18:07:42 -07004855
4856 // add dropbox logging to libcore
4857 DropBox.setReporter(new DropBoxReporter());
4858
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004859 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004860 public void onConfigurationChanged(Configuration newConfig) {
4861 synchronized (mPackages) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004862 // We need to apply this change to the resources
4863 // immediately, because upon returning the view
4864 // hierarchy will be informed about it.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004865 if (applyConfigurationToResourcesLocked(newConfig, null)) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004866 // This actually changed the resources! Tell
4867 // everyone about it.
4868 if (mPendingConfiguration == null ||
4869 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
4870 mPendingConfiguration = newConfig;
4871
4872 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
4873 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004874 }
4875 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004876 }
4877 public void onLowMemory() {
4878 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004879 public void onTrimMemory(int level) {
4880 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004881 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004882 }
4883
Romain Guy5e9120d2012-01-30 12:17:22 -08004884 public static ActivityThread systemMain() {
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004885 HardwareRenderer.disable(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004886 ActivityThread thread = new ActivityThread();
4887 thread.attach(true);
4888 return thread;
4889 }
4890
Jeff Brown10e89712011-07-08 18:52:57 -07004891 public final void installSystemProviders(List<ProviderInfo> providers) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004892 if (providers != null) {
Jeff Brown10e89712011-07-08 18:52:57 -07004893 installContentProviders(mInitialApplication, providers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 }
4895 }
4896
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004897 public int getIntCoreSetting(String key, int defaultValue) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08004898 synchronized (mPackages) {
4899 if (mCoreSettings != null) {
4900 return mCoreSettings.getInt(key, defaultValue);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004901 } else {
4902 return defaultValue;
4903 }
4904 }
4905 }
4906
Geremy Condra69689a72012-09-11 16:57:17 -07004907 private static class EventLoggingReporter implements EventLogger.Reporter {
4908 @Override
4909 public void report (int code, Object... list) {
4910 EventLog.writeEvent(code, list);
4911 }
4912 }
4913
Geremy Condrab7faaf42012-09-19 18:07:42 -07004914 private class DropBoxReporter implements DropBox.Reporter {
4915
4916 private DropBoxManager dropBox;
4917
4918 public DropBoxReporter() {
4919 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
4920 }
4921
4922 @Override
4923 public void addData(String tag, byte[] data, int flags) {
4924 dropBox.addData(tag, data, flags);
4925 }
4926
4927 @Override
4928 public void addText(String tag, String data) {
4929 dropBox.addText(tag, data);
4930 }
4931 }
4932
Romain Guy65b345f2011-07-27 18:51:50 -07004933 public static void main(String[] args) {
Bob Leee5408332009-09-04 18:31:17 -07004934 SamplingProfilerIntegration.start();
4935
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -08004936 // CloseGuard defaults to true and can be quite spammy. We
4937 // disable it here, but selectively enable it later (via
4938 // StrictMode) on debug builds, but using DropBox, not logs.
4939 CloseGuard.setEnabled(false);
4940
Jeff Sharkeyb049e212012-09-07 23:16:01 -07004941 Environment.initForCurrentUser();
4942
Geremy Condra69689a72012-09-11 16:57:17 -07004943 // Set the reporter for event logging in libcore
4944 EventLogger.setReporter(new EventLoggingReporter());
4945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004946 Process.setArgV0("<pre-initialized>");
4947
4948 Looper.prepareMainLooper();
4949
4950 ActivityThread thread = new ActivityThread();
4951 thread.attach(false);
4952
Vairavan Srinivasan7335cfd2012-08-18 18:36:03 -07004953 if (sMainThreadHandler == null) {
4954 sMainThreadHandler = thread.getHandler();
4955 }
4956
Romain Guy5e9120d2012-01-30 12:17:22 -08004957 AsyncTask.init();
4958
Dianne Hackborn287952c2010-09-22 22:34:31 -07004959 if (false) {
4960 Looper.myLooper().setMessageLogging(new
4961 LogPrinter(Log.DEBUG, "ActivityThread"));
4962 }
4963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004964 Looper.loop();
4965
Jeff Brown10e89712011-07-08 18:52:57 -07004966 throw new RuntimeException("Main thread loop unexpectedly exited");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004967 }
4968}