blob: d8808173497e4f8b05464fac61be431742ca9eb0 [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;
Christopher Tate346acb12012-10-15 19:20:25 -070032import android.content.pm.PackageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033import android.content.pm.PackageManager;
Sen Hubde75702010-05-28 01:54:03 -070034import android.content.pm.PackageManager.NameNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import android.content.pm.ProviderInfo;
36import android.content.pm.ServiceInfo;
37import android.content.res.AssetManager;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -070038import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.content.res.Configuration;
40import android.content.res.Resources;
41import android.database.sqlite.SQLiteDatabase;
42import android.database.sqlite.SQLiteDebug;
Vasu Noric3849202010-03-09 10:47:25 -080043import android.database.sqlite.SQLiteDebug.DbStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.graphics.Bitmap;
45import android.graphics.Canvas;
Jeff Brown98365d72012-08-19 20:30:52 -070046import android.hardware.display.DisplayManager;
Jeff Brownbd6e1502012-08-28 03:27:37 -070047import android.hardware.display.DisplayManagerGlobal;
Robert Greenwalt434203a2010-10-11 16:00:27 -070048import android.net.IConnectivityManager;
49import android.net.Proxy;
50import android.net.ProxyProperties;
Romain Guya9582652011-11-10 14:20:10 -080051import android.opengl.GLUtils;
Joe Onoratod630f102011-03-17 18:42:26 -070052import android.os.AsyncTask;
Amith Yamasani742a6712011-05-04 14:49:28 -070053import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.Bundle;
55import android.os.Debug;
Geremy Condrab7faaf42012-09-19 18:07:42 -070056import android.os.DropBoxManager;
Jeff Sharkeyb049e212012-09-07 23:16:01 -070057import android.os.Environment;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.os.Handler;
59import android.os.IBinder;
60import android.os.Looper;
61import android.os.Message;
62import android.os.MessageQueue;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070063import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.os.Process;
65import android.os.RemoteException;
66import android.os.ServiceManager;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -070067import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.os.SystemClock;
Jeff Brownefd43bd2012-09-21 17:02:35 -070069import android.os.SystemProperties;
Dianne Hackborn1ded0b12012-04-26 14:14:50 -070070import android.os.Trace;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070071import android.os.UserHandle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.util.AndroidRuntimeException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073import android.util.DisplayMetrics;
74import android.util.EventLog;
75import android.util.Log;
Dianne Hackborn287952c2010-09-22 22:34:31 -070076import android.util.LogPrinter;
Jeff Brown6754ba22011-12-14 20:20:01 -080077import android.util.PrintWriterPrinter;
Dianne Hackbornc9421ba2010-03-11 22:23:46 -080078import android.util.Slog;
Jeff Brownd32460c2012-07-20 16:15:36 -070079import android.view.CompatibilityInfoHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080080import android.view.Display;
Romain Guy52339202010-09-03 16:04:46 -070081import android.view.HardwareRenderer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import android.view.View;
83import android.view.ViewDebug;
84import android.view.ViewManager;
Dianne Hackborn6dd005b2011-07-18 13:22:50 -070085import android.view.ViewRootImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import android.view.Window;
87import android.view.WindowManager;
Jeff Brown98365d72012-08-19 20:30:52 -070088import android.view.WindowManagerGlobal;
Jason Samsa6f338c2012-02-24 16:22:16 -080089import android.renderscript.RenderScript;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090
91import com.android.internal.os.BinderInternal;
92import com.android.internal.os.RuntimeInit;
Bob Leee5408332009-09-04 18:31:17 -070093import com.android.internal.os.SamplingProfilerIntegration;
Jeff Sharkey6d515712012-09-20 16:06:08 -070094import com.android.internal.util.Objects;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095
96import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
97
98import java.io.File;
99import java.io.FileDescriptor;
100import java.io.FileOutputStream;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700101import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102import java.io.PrintWriter;
103import java.lang.ref.WeakReference;
Robert Greenwalt03595d02010-11-02 14:08:23 -0700104import java.net.InetAddress;
Kenny Roote29df162012-08-10 08:28:37 -0700105import java.security.Security;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106import java.util.ArrayList;
107import java.util.HashMap;
108import java.util.Iterator;
109import java.util.List;
110import java.util.Locale;
111import java.util.Map;
112import java.util.TimeZone;
113import java.util.regex.Pattern;
114
Geremy Condrab7faaf42012-09-19 18:07:42 -0700115import libcore.io.DropBox;
Geremy Condra69689a72012-09-11 16:57:17 -0700116import libcore.io.EventLogger;
Jeff Sharkeye861b422012-03-01 20:59:22 -0800117import libcore.io.IoUtils;
118
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -0800119import dalvik.system.CloseGuard;
Bob Leee5408332009-09-04 18:31:17 -0700120
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121final class SuperNotCalledException extends AndroidRuntimeException {
122 public SuperNotCalledException(String msg) {
123 super(msg);
124 }
125}
126
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700127final class RemoteServiceException extends AndroidRuntimeException {
128 public RemoteServiceException(String msg) {
129 super(msg);
130 }
131}
132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133/**
134 * This manages the execution of the main thread in an
135 * application process, scheduling and executing activities,
136 * broadcasts, and other operations on it as the activity
137 * manager requests.
138 *
139 * {@hide}
140 */
141public final class ActivityThread {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700142 /** @hide */
143 public static final String TAG = "ActivityThread";
Jim Miller0b2a6d02010-07-13 18:01:29 -0700144 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
Joe Onorato43a17652011-04-06 19:22:23 -0700145 static final boolean localLOGV = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700146 static final boolean DEBUG_MESSAGES = false;
Dianne Hackborne829fef2010-10-26 17:44:01 -0700147 /** @hide */
148 public static final boolean DEBUG_BROADCAST = false;
Chris Tate8a7dc172009-03-24 20:11:42 -0700149 private static final boolean DEBUG_RESULTS = false;
Dianne Hackborn755c8bf2012-05-07 15:06:09 -0700150 private static final boolean DEBUG_BACKUP = false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700151 private static final boolean DEBUG_CONFIGURATION = false;
Dianne Hackborna0c283e2012-02-09 10:47:01 -0800152 private static final boolean DEBUG_SERVICE = false;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -0700153 private static final boolean DEBUG_MEMORY_TRIM = false;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700154 private static final boolean DEBUG_PROVIDER = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
156 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
157 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
158 private static final int LOG_ON_PAUSE_CALLED = 30021;
159 private static final int LOG_ON_RESUME_CALLED = 30022;
160
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700161 static ContextImpl mSystemContext = null;
Bob Leee5408332009-09-04 18:31:17 -0700162
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700163 static IPackageManager sPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700165 final ApplicationThread mAppThread = new ApplicationThread();
166 final Looper mLooper = Looper.myLooper();
167 final H mH = new H();
168 final HashMap<IBinder, ActivityClientRecord> mActivities
169 = new HashMap<IBinder, ActivityClientRecord>();
170 // List of new activities (via ActivityRecord.nextIdle) that should
171 // be reported when next we idle.
172 ActivityClientRecord mNewActivities = null;
173 // Number of activities that are currently visible on-screen.
174 int mNumVisibleActivities = 0;
175 final HashMap<IBinder, Service> mServices
176 = new HashMap<IBinder, Service>();
177 AppBindData mBoundApplication;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700178 Profiler mProfiler;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700179 int mCurDefaultDisplayDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -0700180 boolean mDensityCompatMode;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700181 Configuration mConfiguration;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700182 Configuration mCompatConfiguration;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700183 Configuration mResConfiguration;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700184 CompatibilityInfo mResCompatibilityInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700185 Application mInitialApplication;
186 final ArrayList<Application> mAllApplications
187 = new ArrayList<Application>();
188 // set of instantiated backup agents, keyed by package name
189 final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
Romain Guy65b345f2011-07-27 18:51:50 -0700190 static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700191 Instrumentation mInstrumentation;
192 String mInstrumentationAppDir = null;
Brian Carlstromd893a892012-04-01 21:30:26 -0700193 String mInstrumentationAppLibraryDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700194 String mInstrumentationAppPackage = null;
195 String mInstrumentedAppDir = null;
Brian Carlstromd893a892012-04-01 21:30:26 -0700196 String mInstrumentedAppLibraryDir = null;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700197 boolean mSystemThread = false;
198 boolean mJitEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700200 // These can be accessed by multiple threads; mPackages is the lock.
201 // XXX For now we keep around information about all packages we have
202 // seen, not removing entries from this map.
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800203 // NOTE: The activity and window managers need to call in to
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700204 // ActivityThread to do things like update resource configurations,
Dianne Hackborn1fbee792011-11-30 11:29:58 -0800205 // which means this lock gets held while the activity and window managers
206 // holds their own lock. Thus you MUST NEVER call back into the activity manager
207 // or window manager or anything that depends on them while holding this lock.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700208 final HashMap<String, WeakReference<LoadedApk>> mPackages
209 = new HashMap<String, WeakReference<LoadedApk>>();
210 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
211 = new HashMap<String, WeakReference<LoadedApk>>();
Jeff Browna492c3a2012-08-23 19:48:44 -0700212 final HashMap<CompatibilityInfo, DisplayMetrics> mDefaultDisplayMetrics
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700213 = new HashMap<CompatibilityInfo, DisplayMetrics>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700214 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
215 = new HashMap<ResourcesKey, WeakReference<Resources> >();
216 final ArrayList<ActivityClientRecord> mRelaunchingActivities
217 = new ArrayList<ActivityClientRecord>();
218 Configuration mPendingConfiguration = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800219
Jeff Sharkey6d515712012-09-20 16:06:08 -0700220 private static final class ProviderKey {
221 final String authority;
222 final int userId;
223
224 public ProviderKey(String authority, int userId) {
225 this.authority = authority;
226 this.userId = userId;
227 }
228
229 @Override
230 public boolean equals(Object o) {
231 if (o instanceof ProviderKey) {
232 final ProviderKey other = (ProviderKey) o;
233 return Objects.equal(authority, other.authority) && userId == other.userId;
234 }
235 return false;
236 }
237
238 @Override
239 public int hashCode() {
240 return ((authority != null) ? authority.hashCode() : 0) ^ userId;
241 }
242 }
243
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700244 // The lock of mProviderMap protects the following variables.
Jeff Sharkey6d515712012-09-20 16:06:08 -0700245 final HashMap<ProviderKey, ProviderClientRecord> mProviderMap
246 = new HashMap<ProviderKey, ProviderClientRecord>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700247 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
248 = new HashMap<IBinder, ProviderRefCount>();
249 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
250 = new HashMap<IBinder, ProviderClientRecord>();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700251 final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName
252 = new HashMap<ComponentName, ProviderClientRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800253
Jeff Hamilton52d32032011-01-08 15:31:26 -0600254 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
255 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
256
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700257 final GcIdler mGcIdler = new GcIdler();
258 boolean mGcIdlerScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700260 static Handler sMainThreadHandler; // set once in main()
261
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800262 Bundle mCoreSettings = null;
263
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400264 static final class ActivityClientRecord {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 IBinder token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700266 int ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800267 Intent intent;
268 Bundle state;
269 Activity activity;
270 Window window;
271 Activity parent;
272 String embeddedID;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -0700273 Activity.NonConfigurationInstances lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800274 boolean paused;
275 boolean stopped;
276 boolean hideForNow;
277 Configuration newConfig;
Dianne Hackborne88846e2009-09-30 21:34:25 -0700278 Configuration createdConfig;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700279 ActivityClientRecord nextIdle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700281 String profileFile;
282 ParcelFileDescriptor profileFd;
283 boolean autoStopProfiler;
284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 ActivityInfo activityInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400286 CompatibilityInfo compatInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700287 LoadedApk packageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288
289 List<ResultInfo> pendingResults;
290 List<Intent> pendingIntents;
291
292 boolean startsNotResumed;
293 boolean isForward;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800294 int pendingConfigChanges;
295 boolean onlyLocalRequest;
296
297 View mPendingRemoveWindow;
298 WindowManager mPendingRemoveWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800299
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700300 ActivityClientRecord() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800301 parent = null;
302 embeddedID = null;
303 paused = false;
304 stopped = false;
305 hideForNow = false;
306 nextIdle = null;
307 }
308
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800309 public boolean isPreHoneycomb() {
310 if (activity != null) {
311 return activity.getApplicationInfo().targetSdkVersion
312 < android.os.Build.VERSION_CODES.HONEYCOMB;
313 }
314 return false;
315 }
316
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800317 public String toString() {
Dianne Hackbornb61a0262012-05-14 17:19:18 -0700318 ComponentName componentName = intent != null ? intent.getComponent() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 return "ActivityRecord{"
320 + Integer.toHexString(System.identityHashCode(this))
321 + " token=" + token + " " + (componentName == null
322 ? "no component name" : componentName.toShortString())
323 + "}";
324 }
325 }
326
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700327 final class ProviderClientRecord {
328 final String[] mNames;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800329 final IContentProvider mProvider;
330 final ContentProvider mLocalProvider;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700331 final IActivityManager.ContentProviderHolder mHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700333 ProviderClientRecord(String[] names, IContentProvider provider,
334 ContentProvider localProvider,
335 IActivityManager.ContentProviderHolder holder) {
336 mNames = names;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 mProvider = provider;
338 mLocalProvider = localProvider;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -0700339 mHolder = holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 }
341 }
342
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400343 static final class NewIntentData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800344 List<Intent> intents;
345 IBinder token;
346 public String toString() {
347 return "NewIntentData{intents=" + intents + " token=" + token + "}";
348 }
349 }
350
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400351 static final class ReceiverData extends BroadcastReceiver.PendingResult {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700352 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700353 boolean ordered, boolean sticky, IBinder token, int sendingUser) {
354 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
355 token, sendingUser);
Dianne Hackborne829fef2010-10-26 17:44:01 -0700356 this.intent = intent;
357 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 Intent intent;
360 ActivityInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400361 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 public String toString() {
363 return "ReceiverData{intent=" + intent + " packageName=" +
Dianne Hackborne829fef2010-10-26 17:44:01 -0700364 info.packageName + " resultCode=" + getResultCode()
365 + " resultData=" + getResultData() + " resultExtras="
366 + getResultExtras(false) + "}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800367 }
368 }
369
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400370 static final class CreateBackupAgentData {
Christopher Tate181fafa2009-05-14 11:12:14 -0700371 ApplicationInfo appInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400372 CompatibilityInfo compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700373 int backupMode;
374 public String toString() {
375 return "CreateBackupAgentData{appInfo=" + appInfo
376 + " backupAgent=" + appInfo.backupAgentName
377 + " mode=" + backupMode + "}";
378 }
379 }
Bob Leee5408332009-09-04 18:31:17 -0700380
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400381 static final class CreateServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 IBinder token;
383 ServiceInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400384 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 Intent intent;
386 public String toString() {
387 return "CreateServiceData{token=" + token + " className="
388 + info.name + " packageName=" + info.packageName
389 + " intent=" + intent + "}";
390 }
391 }
392
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400393 static final class BindServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394 IBinder token;
395 Intent intent;
396 boolean rebind;
397 public String toString() {
398 return "BindServiceData{token=" + token + " intent=" + intent + "}";
399 }
400 }
401
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400402 static final class ServiceArgsData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 IBinder token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700404 boolean taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 int startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700406 int flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800407 Intent args;
408 public String toString() {
409 return "ServiceArgsData{token=" + token + " startId=" + startId
410 + " args=" + args + "}";
411 }
412 }
413
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400414 static final class AppBindData {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700415 LoadedApk info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800416 String processName;
417 ApplicationInfo appInfo;
418 List<ProviderInfo> providers;
419 ComponentName instrumentationName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420 Bundle instrumentationArgs;
421 IInstrumentationWatcher instrumentationWatcher;
422 int debugMode;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800423 boolean enableOpenGlTrace;
Christopher Tate181fafa2009-05-14 11:12:14 -0700424 boolean restrictedBackupMode;
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700425 boolean persistent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800426 Configuration config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400427 CompatibilityInfo compatInfo;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700428
429 /** Initial values for {@link Profiler}. */
430 String initProfileFile;
431 ParcelFileDescriptor initProfileFd;
432 boolean initAutoStopProfiler;
433
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800434 public String toString() {
435 return "AppBindData{appInfo=" + appInfo + "}";
436 }
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700437 }
438
439 static final class Profiler {
440 String profileFile;
441 ParcelFileDescriptor profileFd;
442 boolean autoStopProfiler;
443 boolean profiling;
444 boolean handlingProfiling;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700445 public void setProfiler(String file, ParcelFileDescriptor fd) {
446 if (profiling) {
447 if (fd != null) {
448 try {
449 fd.close();
450 } catch (IOException e) {
Romain Guya998dff2012-03-23 18:58:36 -0700451 // Ignore
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700452 }
453 }
454 return;
455 }
456 if (profileFd != null) {
457 try {
458 profileFd.close();
459 } catch (IOException e) {
Romain Guya998dff2012-03-23 18:58:36 -0700460 // Ignore
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700461 }
462 }
463 profileFile = file;
464 profileFd = fd;
465 }
466 public void startProfiling() {
467 if (profileFd == null || profiling) {
468 return;
469 }
470 try {
471 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(),
472 8 * 1024 * 1024, 0);
473 profiling = true;
474 } catch (RuntimeException e) {
475 Slog.w(TAG, "Profiling failed on path " + profileFile);
476 try {
477 profileFd.close();
478 profileFd = null;
479 } catch (IOException e2) {
480 Slog.w(TAG, "Failure closing profile fd", e2);
481 }
482 }
483 }
484 public void stopProfiling() {
485 if (profiling) {
486 profiling = false;
487 Debug.stopMethodTracing();
488 if (profileFd != null) {
489 try {
490 profileFd.close();
491 } catch (IOException e) {
492 }
493 }
494 profileFd = null;
495 profileFile = null;
496 }
497 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800498 }
499
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400500 static final class DumpComponentInfo {
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700501 ParcelFileDescriptor fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700502 IBinder token;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800503 String prefix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 String[] args;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800505 }
506
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400507 static final class ResultData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800508 IBinder token;
509 List<ResultInfo> results;
510 public String toString() {
511 return "ResultData{token=" + token + " results" + results + "}";
512 }
513 }
514
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400515 static final class ContextCleanupInfo {
Dianne Hackborn21556372010-02-04 16:34:40 -0800516 ContextImpl context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 String what;
518 String who;
519 }
520
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400521 static final class ProfilerControlData {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700522 String path;
523 ParcelFileDescriptor fd;
524 }
525
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400526 static final class DumpHeapData {
Andy McFadden824c5102010-07-09 16:26:57 -0700527 String path;
528 ParcelFileDescriptor fd;
529 }
530
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400531 static final class UpdateCompatibilityData {
532 String pkg;
533 CompatibilityInfo info;
534 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -0700535
Romain Guy65b345f2011-07-27 18:51:50 -0700536 private native void dumpGraphicsInfo(FileDescriptor fd);
Chet Haase9c1e23b2011-03-24 10:51:31 -0700537
Romain Guy65b345f2011-07-27 18:51:50 -0700538 private class ApplicationThread extends ApplicationThreadNative {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700539 private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
540 private static final String ONE_COUNT_COLUMN = "%21s %8d";
541 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
Vasu Nori3c7131f2010-09-21 14:36:57 -0700542 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
Bob Leee5408332009-09-04 18:31:17 -0700543
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 // Formatting for checkin service - update version if row format changes
545 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
Bob Leee5408332009-09-04 18:31:17 -0700546
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700547 private void updatePendingConfiguration(Configuration config) {
548 synchronized (mPackages) {
549 if (mPendingConfiguration == null ||
550 mPendingConfiguration.isOtherSeqNewer(config)) {
551 mPendingConfiguration = config;
552 }
553 }
554 }
555
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800556 public final void schedulePauseActivity(IBinder token, boolean finished,
557 boolean userLeaving, int configChanges) {
558 queueOrSendMessage(
559 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
560 token,
561 (userLeaving ? 1 : 0),
562 configChanges);
563 }
564
565 public final void scheduleStopActivity(IBinder token, boolean showWindow,
566 int configChanges) {
567 queueOrSendMessage(
568 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
569 token, 0, configChanges);
570 }
571
572 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
573 queueOrSendMessage(
574 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
575 token);
576 }
577
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800578 public final void scheduleSleeping(IBinder token, boolean sleeping) {
579 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
580 }
581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800582 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
583 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
584 }
585
586 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
587 ResultData res = new ResultData();
588 res.token = token;
589 res.results = results;
590 queueOrSendMessage(H.SEND_RESULT, res);
591 }
592
593 // we use token to identify this activity without having to send the
594 // activity itself back to the activity manager. (matters more with ipc)
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700595 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700596 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo,
597 Bundle state, List<ResultInfo> pendingResults,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700598 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward,
599 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700600 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800601
602 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700603 r.ident = ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 r.intent = intent;
605 r.activityInfo = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400606 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800607 r.state = state;
608
609 r.pendingResults = pendingResults;
610 r.pendingIntents = pendingNewIntents;
611
612 r.startsNotResumed = notResumed;
613 r.isForward = isForward;
614
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700615 r.profileFile = profileName;
616 r.profileFd = profileFd;
617 r.autoStopProfiler = autoStopProfiler;
618
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700619 updatePendingConfiguration(curConfig);
620
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800621 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
622 }
623
624 public final void scheduleRelaunchActivity(IBinder token,
625 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
Dianne Hackborn871ecdc2009-12-11 15:24:33 -0800626 int configChanges, boolean notResumed, Configuration config) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800627 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
628 configChanges, notResumed, config, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800629 }
630
631 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
632 NewIntentData data = new NewIntentData();
633 data.intents = intents;
634 data.token = token;
635
636 queueOrSendMessage(H.NEW_INTENT, data);
637 }
638
639 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
640 int configChanges) {
641 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
642 configChanges);
643 }
644
645 public final void scheduleReceiver(Intent intent, ActivityInfo info,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400646 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700647 boolean sync, int sendingUser) {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700648 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700649 sync, false, mAppThread.asBinder(), sendingUser);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 r.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400651 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800652 queueOrSendMessage(H.RECEIVER, r);
653 }
654
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400655 public final void scheduleCreateBackupAgent(ApplicationInfo app,
656 CompatibilityInfo compatInfo, int backupMode) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700657 CreateBackupAgentData d = new CreateBackupAgentData();
658 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400659 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700660 d.backupMode = backupMode;
661
662 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
663 }
664
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400665 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
666 CompatibilityInfo compatInfo) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700667 CreateBackupAgentData d = new CreateBackupAgentData();
668 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400669 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700670
671 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
672 }
673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800674 public final void scheduleCreateService(IBinder token,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400675 ServiceInfo info, CompatibilityInfo compatInfo) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800676 CreateServiceData s = new CreateServiceData();
677 s.token = token;
678 s.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400679 s.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800680
681 queueOrSendMessage(H.CREATE_SERVICE, s);
682 }
683
684 public final void scheduleBindService(IBinder token, Intent intent,
685 boolean rebind) {
686 BindServiceData s = new BindServiceData();
687 s.token = token;
688 s.intent = intent;
689 s.rebind = rebind;
690
Amith Yamasani742a6712011-05-04 14:49:28 -0700691 if (DEBUG_SERVICE)
692 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid="
693 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800694 queueOrSendMessage(H.BIND_SERVICE, s);
695 }
696
697 public final void scheduleUnbindService(IBinder token, Intent intent) {
698 BindServiceData s = new BindServiceData();
699 s.token = token;
700 s.intent = intent;
701
702 queueOrSendMessage(H.UNBIND_SERVICE, s);
703 }
704
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700705 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700706 int flags ,Intent args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800707 ServiceArgsData s = new ServiceArgsData();
708 s.token = token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700709 s.taskRemoved = taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800710 s.startId = startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700711 s.flags = flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800712 s.args = args;
713
714 queueOrSendMessage(H.SERVICE_ARGS, s);
715 }
716
717 public final void scheduleStopService(IBinder token) {
718 queueOrSendMessage(H.STOP_SERVICE, token);
719 }
720
721 public final void bindApplication(String processName,
722 ApplicationInfo appInfo, List<ProviderInfo> providers,
723 ComponentName instrumentationName, String profileFile,
Dianne Hackborn62f20ec2011-08-15 17:40:28 -0700724 ParcelFileDescriptor profileFd, boolean autoStopProfiler,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800725 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
Siva Velusamy92a8b222012-03-09 16:24:04 -0800726 int debugMode, boolean enableOpenGlTrace, boolean isRestrictedBackupMode,
727 boolean persistent, Configuration config, CompatibilityInfo compatInfo,
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700728 Map<String, IBinder> services, Bundle coreSettings) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729
730 if (services != null) {
731 // Setup the service cache in the ServiceManager
732 ServiceManager.initServiceCache(services);
733 }
734
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800735 setCoreSettings(coreSettings);
736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 AppBindData data = new AppBindData();
738 data.processName = processName;
739 data.appInfo = appInfo;
740 data.providers = providers;
741 data.instrumentationName = instrumentationName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800742 data.instrumentationArgs = instrumentationArgs;
743 data.instrumentationWatcher = instrumentationWatcher;
744 data.debugMode = debugMode;
Siva Velusamy92a8b222012-03-09 16:24:04 -0800745 data.enableOpenGlTrace = enableOpenGlTrace;
Christopher Tate181fafa2009-05-14 11:12:14 -0700746 data.restrictedBackupMode = isRestrictedBackupMode;
Dianne Hackborn5d927c22011-09-02 12:22:18 -0700747 data.persistent = persistent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 data.config = config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400749 data.compatInfo = compatInfo;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -0700750 data.initProfileFile = profileFile;
751 data.initProfileFd = profileFd;
752 data.initAutoStopProfiler = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 queueOrSendMessage(H.BIND_APPLICATION, data);
754 }
755
756 public final void scheduleExit() {
757 queueOrSendMessage(H.EXIT_APPLICATION, null);
758 }
759
Christopher Tate5e1ab332009-09-01 20:32:49 -0700760 public final void scheduleSuicide() {
761 queueOrSendMessage(H.SUICIDE, null);
762 }
763
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800764 public void requestThumbnail(IBinder token) {
765 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
766 }
767
768 public void scheduleConfigurationChanged(Configuration config) {
Dianne Hackborn58f42a52011-10-10 13:46:34 -0700769 updatePendingConfiguration(config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
771 }
772
773 public void updateTimeZone() {
774 TimeZone.setDefault(null);
775 }
776
Robert Greenwalt03595d02010-11-02 14:08:23 -0700777 public void clearDnsCache() {
778 // a non-standard API to get this to libcore
779 InetAddress.clearDnsCache();
780 }
781
Robert Greenwalt434203a2010-10-11 16:00:27 -0700782 public void setHttpProxy(String host, String port, String exclList) {
783 Proxy.setHttpProxySystemProperty(host, port, exclList);
784 }
785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 public void processInBackground() {
787 mH.removeMessages(H.GC_WHEN_IDLE);
788 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
789 }
790
791 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700792 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700793 try {
794 data.fd = ParcelFileDescriptor.dup(fd);
795 data.token = servicetoken;
796 data.args = args;
797 queueOrSendMessage(H.DUMP_SERVICE, data);
798 } catch (IOException e) {
799 Slog.w(TAG, "dumpService failed", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 }
801 }
802
803 // This function exists to make sure all receiver dispatching is
804 // correctly ordered, since these are one-way calls and the binder driver
805 // applies transaction ordering per object for such calls.
806 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
Dianne Hackborn68d881c2009-10-05 13:58:17 -0700807 int resultCode, String dataStr, Bundle extras, boolean ordered,
Dianne Hackborn20e80982012-08-31 19:00:44 -0700808 boolean sticky, int sendingUser) throws RemoteException {
809 receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
810 sticky, sendingUser);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800811 }
Bob Leee5408332009-09-04 18:31:17 -0700812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 public void scheduleLowMemory() {
814 queueOrSendMessage(H.LOW_MEMORY, null);
815 }
816
817 public void scheduleActivityConfigurationChanged(IBinder token) {
818 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
819 }
820
Romain Guy7eabe552011-07-21 14:56:34 -0700821 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
822 int profileType) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700823 ProfilerControlData pcd = new ProfilerControlData();
824 pcd.path = path;
825 pcd.fd = fd;
Romain Guy7eabe552011-07-21 14:56:34 -0700826 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800827 }
828
Andy McFadden824c5102010-07-09 16:26:57 -0700829 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
830 DumpHeapData dhd = new DumpHeapData();
831 dhd.path = path;
832 dhd.fd = fd;
833 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
834 }
835
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700836 public void setSchedulingGroup(int group) {
837 // Note: do this immediately, since going into the foreground
838 // should happen regardless of what pending work we have to do
839 // and the activity manager will wait for us to report back that
840 // we are done before sending us to the background.
841 try {
842 Process.setProcessGroup(Process.myPid(), group);
843 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800844 Slog.w(TAG, "Failed setting process group to " + group, e);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700845 }
846 }
Bob Leee5408332009-09-04 18:31:17 -0700847
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700848 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
849 Debug.getMemoryInfo(outInfo);
850 }
Bob Leee5408332009-09-04 18:31:17 -0700851
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700852 public void dispatchPackageBroadcast(int cmd, String[] packages) {
853 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
854 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700855
856 public void scheduleCrash(String msg) {
857 queueOrSendMessage(H.SCHEDULE_CRASH, msg);
858 }
Dianne Hackborn625ac272010-09-17 18:29:22 -0700859
Dianne Hackborn30d71892010-12-11 10:37:55 -0800860 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
861 String prefix, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700862 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700863 try {
864 data.fd = ParcelFileDescriptor.dup(fd);
865 data.token = activitytoken;
866 data.prefix = prefix;
867 data.args = args;
868 queueOrSendMessage(H.DUMP_ACTIVITY, data);
869 } catch (IOException e) {
870 Slog.w(TAG, "dumpActivity failed", e);
Dianne Hackborn625ac272010-09-17 18:29:22 -0700871 }
872 }
Chet Haase9c1e23b2011-03-24 10:51:31 -0700873
Marco Nelissen18cb2872011-11-15 11:19:53 -0800874 public void dumpProvider(FileDescriptor fd, IBinder providertoken,
875 String[] args) {
876 DumpComponentInfo data = new DumpComponentInfo();
877 try {
878 data.fd = ParcelFileDescriptor.dup(fd);
879 data.token = providertoken;
880 data.args = args;
881 queueOrSendMessage(H.DUMP_PROVIDER, data);
882 } catch (IOException e) {
883 Slog.w(TAG, "dumpProvider failed", e);
884 }
885 }
886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800887 @Override
Dianne Hackbornb437e092011-08-05 17:50:29 -0700888 public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin,
889 boolean all, String[] args) {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700890 FileOutputStream fout = new FileOutputStream(fd);
891 PrintWriter pw = new PrintWriter(fout);
892 try {
Romain Guya998dff2012-03-23 18:58:36 -0700893 return dumpMemInfo(pw, checkin, all);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700894 } finally {
Chet Haase9c1e23b2011-03-24 10:51:31 -0700895 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -0700896 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700897 }
898
Romain Guya998dff2012-03-23 18:58:36 -0700899 private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean all) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 long nativeMax = Debug.getNativeHeapSize() / 1024;
901 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
902 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
903
904 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
905 Debug.getMemoryInfo(memInfo);
906
Dianne Hackbornb437e092011-08-05 17:50:29 -0700907 if (!all) {
908 return memInfo;
909 }
910
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 Runtime runtime = Runtime.getRuntime();
912
913 long dalvikMax = runtime.totalMemory() / 1024;
914 long dalvikFree = runtime.freeMemory() / 1024;
915 long dalvikAllocated = dalvikMax - dalvikFree;
916 long viewInstanceCount = ViewDebug.getViewInstanceCount();
Romain Guy65b345f2011-07-27 18:51:50 -0700917 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
Brian Carlstromc21550a2010-10-05 21:34:06 -0700918 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
919 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920 int globalAssetCount = AssetManager.getGlobalAssetCount();
921 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
922 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
923 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
924 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
Brian Carlstromc9d5b312010-10-05 22:23:41 -0700925 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
Vasu Noric3849202010-03-09 10:47:25 -0800926 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
Bob Leee5408332009-09-04 18:31:17 -0700927
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 // For checkin, we print one long comma-separated list of values
Dianne Hackbornb437e092011-08-05 17:50:29 -0700929 if (checkin) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 // NOTE: if you change anything significant below, also consider changing
931 // ACTIVITY_THREAD_CHECKIN_VERSION.
Bob Leee5408332009-09-04 18:31:17 -0700932 String processName = (mBoundApplication != null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 ? mBoundApplication.processName : "unknown";
Bob Leee5408332009-09-04 18:31:17 -0700934
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 // Header
936 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
937 pw.print(Process.myPid()); pw.print(',');
938 pw.print(processName); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 // Heap info - max
941 pw.print(nativeMax); pw.print(',');
942 pw.print(dalvikMax); pw.print(',');
943 pw.print("N/A,");
944 pw.print(nativeMax + dalvikMax); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800946 // Heap info - allocated
947 pw.print(nativeAllocated); pw.print(',');
948 pw.print(dalvikAllocated); pw.print(',');
949 pw.print("N/A,");
950 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800952 // Heap info - free
953 pw.print(nativeFree); pw.print(',');
954 pw.print(dalvikFree); pw.print(',');
955 pw.print("N/A,");
956 pw.print(nativeFree + dalvikFree); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 // Heap info - proportional set size
959 pw.print(memInfo.nativePss); pw.print(',');
960 pw.print(memInfo.dalvikPss); pw.print(',');
961 pw.print(memInfo.otherPss); pw.print(',');
962 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700963
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 // Heap info - shared
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700965 pw.print(memInfo.nativeSharedDirty); pw.print(',');
966 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
967 pw.print(memInfo.otherSharedDirty); pw.print(',');
968 pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
969 + memInfo.otherSharedDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700970
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800971 // Heap info - private
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700972 pw.print(memInfo.nativePrivateDirty); pw.print(',');
973 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
974 pw.print(memInfo.otherPrivateDirty); pw.print(',');
975 pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
976 + memInfo.otherPrivateDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700977
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 // Object counts
979 pw.print(viewInstanceCount); pw.print(',');
980 pw.print(viewRootInstanceCount); pw.print(',');
981 pw.print(appContextInstanceCount); pw.print(',');
982 pw.print(activityInstanceCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700983
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 pw.print(globalAssetCount); pw.print(',');
985 pw.print(globalAssetManagerCount); pw.print(',');
986 pw.print(binderLocalObjectCount); pw.print(',');
987 pw.print(binderProxyObjectCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800989 pw.print(binderDeathObjectCount); pw.print(',');
990 pw.print(openSslSocketCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700991
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 // SQL
Vasu Noric3849202010-03-09 10:47:25 -0800993 pw.print(stats.memoryUsed / 1024); pw.print(',');
Jeff Brown2a293b62012-01-19 14:02:22 -0800994 pw.print(stats.memoryUsed / 1024); pw.print(',');
995 pw.print(stats.pageCacheOverflow / 1024); pw.print(',');
Dianne Hackbornb437e092011-08-05 17:50:29 -0700996 pw.print(stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -0800997 for (int i = 0; i < stats.dbStats.size(); i++) {
998 DbStats dbStats = stats.dbStats.get(i);
Dianne Hackbornb437e092011-08-05 17:50:29 -0700999 pw.print(','); pw.print(dbStats.dbName);
1000 pw.print(','); pw.print(dbStats.pageSize);
1001 pw.print(','); pw.print(dbStats.dbSize);
1002 pw.print(','); pw.print(dbStats.lookaside);
1003 pw.print(','); pw.print(dbStats.cache);
1004 pw.print(','); pw.print(dbStats.cache);
Vasu Noric3849202010-03-09 10:47:25 -08001005 }
Dianne Hackbornb437e092011-08-05 17:50:29 -07001006 pw.println();
Bob Leee5408332009-09-04 18:31:17 -07001007
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001008 return memInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001009 }
Bob Leee5408332009-09-04 18:31:17 -07001010
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 // otherwise, show human-readable format
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001012 printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
1013 printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
1014 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
1015 "------");
1016 printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
1017 memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
1018 printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
1019 memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001021 int otherPss = memInfo.otherPss;
1022 int otherSharedDirty = memInfo.otherSharedDirty;
1023 int otherPrivateDirty = memInfo.otherPrivateDirty;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001024
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001025 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
Romain Guy65b345f2011-07-27 18:51:50 -07001026 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001027 memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
1028 memInfo.getOtherPrivateDirty(i), "", "", "");
1029 otherPss -= memInfo.getOtherPss(i);
1030 otherSharedDirty -= memInfo.getOtherSharedDirty(i);
1031 otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
1032 }
1033
1034 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
1035 otherPrivateDirty, "", "", "");
1036 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
1037 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
1038 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
1039 nativeFree+dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001040
1041 pw.println(" ");
1042 pw.println(" Objects");
Romain Guy65b345f2011-07-27 18:51:50 -07001043 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 viewRootInstanceCount);
1045
1046 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
1047 "Activities:", activityInstanceCount);
1048
1049 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
1050 "AssetManagers:", globalAssetManagerCount);
1051
1052 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
1053 "Proxy Binders:", binderProxyObjectCount);
1054 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
1055
1056 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
Bob Leee5408332009-09-04 18:31:17 -07001057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001058 // SQLite mem info
1059 pw.println(" ");
1060 pw.println(" SQL");
Jeff Brown2a293b62012-01-19 14:02:22 -08001061 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024);
1062 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:",
1063 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -08001064 pw.println(" ");
1065 int N = stats.dbStats.size();
1066 if (N > 0) {
1067 pw.println(" DATABASES");
Vasu Nori3c7131f2010-09-21 14:36:57 -07001068 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
1069 "Dbname");
Vasu Noric3849202010-03-09 10:47:25 -08001070 for (int i = 0; i < N; i++) {
1071 DbStats dbStats = stats.dbStats.get(i);
Vasu Nori3c7131f2010-09-21 14:36:57 -07001072 printRow(pw, DB_INFO_FORMAT,
1073 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
1074 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
1075 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
1076 dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -08001077 }
1078 }
Bob Leee5408332009-09-04 18:31:17 -07001079
Dianne Hackborn82e1ee92009-08-11 18:56:41 -07001080 // Asset details.
1081 String assetAlloc = AssetManager.getAssetAllocations();
1082 if (assetAlloc != null) {
1083 pw.println(" ");
1084 pw.println(" Asset Allocations");
1085 pw.print(assetAlloc);
1086 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -07001087
1088 return memInfo;
1089 }
1090
1091 @Override
1092 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
1093 dumpGraphicsInfo(fd);
Jeff Brown98365d72012-08-19 20:30:52 -07001094 WindowManagerGlobal.getInstance().dumpGfxInfo(fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001095 }
1096
Jeff Brown6754ba22011-12-14 20:20:01 -08001097 @Override
1098 public void dumpDbInfo(FileDescriptor fd, String[] args) {
1099 PrintWriter pw = new PrintWriter(new FileOutputStream(fd));
1100 PrintWriterPrinter printer = new PrintWriterPrinter(pw);
1101 SQLiteDebug.dump(printer, args);
1102 pw.flush();
1103 }
1104
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001105 @Override
1106 public void unstableProviderDied(IBinder provider) {
1107 queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
1108 }
1109
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001110 private void printRow(PrintWriter pw, String format, Object...objs) {
1111 pw.println(String.format(format, objs));
1112 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001113
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08001114 public void setCoreSettings(Bundle coreSettings) {
1115 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001116 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001117
1118 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
1119 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
1120 ucd.pkg = pkg;
1121 ucd.info = info;
1122 queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
1123 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001124
1125 public void scheduleTrimMemory(int level) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001126 queueOrSendMessage(H.TRIM_MEMORY, null, level);
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001127 }
Marco Nelissen18cb2872011-11-15 11:19:53 -08001128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 }
1130
Romain Guy65b345f2011-07-27 18:51:50 -07001131 private class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 public static final int LAUNCH_ACTIVITY = 100;
1133 public static final int PAUSE_ACTIVITY = 101;
1134 public static final int PAUSE_ACTIVITY_FINISHING= 102;
1135 public static final int STOP_ACTIVITY_SHOW = 103;
1136 public static final int STOP_ACTIVITY_HIDE = 104;
1137 public static final int SHOW_WINDOW = 105;
1138 public static final int HIDE_WINDOW = 106;
1139 public static final int RESUME_ACTIVITY = 107;
1140 public static final int SEND_RESULT = 108;
Brian Carlstromed7e0072011-03-24 13:27:57 -07001141 public static final int DESTROY_ACTIVITY = 109;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 public static final int BIND_APPLICATION = 110;
1143 public static final int EXIT_APPLICATION = 111;
1144 public static final int NEW_INTENT = 112;
1145 public static final int RECEIVER = 113;
1146 public static final int CREATE_SERVICE = 114;
1147 public static final int SERVICE_ARGS = 115;
1148 public static final int STOP_SERVICE = 116;
1149 public static final int REQUEST_THUMBNAIL = 117;
1150 public static final int CONFIGURATION_CHANGED = 118;
1151 public static final int CLEAN_UP_CONTEXT = 119;
1152 public static final int GC_WHEN_IDLE = 120;
1153 public static final int BIND_SERVICE = 121;
1154 public static final int UNBIND_SERVICE = 122;
1155 public static final int DUMP_SERVICE = 123;
1156 public static final int LOW_MEMORY = 124;
1157 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
1158 public static final int RELAUNCH_ACTIVITY = 126;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001159 public static final int PROFILER_CONTROL = 127;
Christopher Tate181fafa2009-05-14 11:12:14 -07001160 public static final int CREATE_BACKUP_AGENT = 128;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001161 public static final int DESTROY_BACKUP_AGENT = 129;
1162 public static final int SUICIDE = 130;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001163 public static final int REMOVE_PROVIDER = 131;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001164 public static final int ENABLE_JIT = 132;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001165 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001166 public static final int SCHEDULE_CRASH = 134;
Andy McFadden824c5102010-07-09 16:26:57 -07001167 public static final int DUMP_HEAP = 135;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001168 public static final int DUMP_ACTIVITY = 136;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001169 public static final int SLEEPING = 137;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001170 public static final int SET_CORE_SETTINGS = 138;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001171 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001172 public static final int TRIM_MEMORY = 140;
Marco Nelissen18cb2872011-11-15 11:19:53 -08001173 public static final int DUMP_PROVIDER = 141;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001174 public static final int UNSTABLE_PROVIDER_DIED = 142;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001175 String codeToString(int code) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001176 if (DEBUG_MESSAGES) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 switch (code) {
1178 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1179 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1180 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1181 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1182 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1183 case SHOW_WINDOW: return "SHOW_WINDOW";
1184 case HIDE_WINDOW: return "HIDE_WINDOW";
1185 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1186 case SEND_RESULT: return "SEND_RESULT";
1187 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1188 case BIND_APPLICATION: return "BIND_APPLICATION";
1189 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1190 case NEW_INTENT: return "NEW_INTENT";
1191 case RECEIVER: return "RECEIVER";
1192 case CREATE_SERVICE: return "CREATE_SERVICE";
1193 case SERVICE_ARGS: return "SERVICE_ARGS";
1194 case STOP_SERVICE: return "STOP_SERVICE";
1195 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
1196 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1197 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1198 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1199 case BIND_SERVICE: return "BIND_SERVICE";
1200 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1201 case DUMP_SERVICE: return "DUMP_SERVICE";
1202 case LOW_MEMORY: return "LOW_MEMORY";
1203 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1204 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001205 case PROFILER_CONTROL: return "PROFILER_CONTROL";
Christopher Tate181fafa2009-05-14 11:12:14 -07001206 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1207 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
Christopher Tate5e1ab332009-09-01 20:32:49 -07001208 case SUICIDE: return "SUICIDE";
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001209 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001210 case ENABLE_JIT: return "ENABLE_JIT";
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001211 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001212 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
Andy McFadden824c5102010-07-09 16:26:57 -07001213 case DUMP_HEAP: return "DUMP_HEAP";
Dianne Hackborn625ac272010-09-17 18:29:22 -07001214 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001215 case SLEEPING: return "SLEEPING";
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001216 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001217 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001218 case TRIM_MEMORY: return "TRIM_MEMORY";
Marco Nelissen18cb2872011-11-15 11:19:53 -08001219 case DUMP_PROVIDER: return "DUMP_PROVIDER";
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001220 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 }
1222 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001223 return Integer.toString(code);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 }
1225 public void handleMessage(Message msg) {
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001226 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001227 switch (msg.what) {
1228 case LAUNCH_ACTIVITY: {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001229 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001230 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231
1232 r.packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001233 r.activityInfo.applicationInfo, r.compatInfo);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001234 handleLaunchActivity(r, null);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001235 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 } break;
1237 case RELAUNCH_ACTIVITY: {
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001238 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart");
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001239 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08001240 handleRelaunchActivity(r);
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 PAUSE_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001244 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
Bob Leee5408332009-09-04 18:31:17 -07001246 maybeSnapshot();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001247 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001248 break;
1249 case PAUSE_ACTIVITY_FINISHING:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001250 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
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 STOP_ACTIVITY_SHOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001255 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001256 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
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 STOP_ACTIVITY_HIDE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001260 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001262 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 break;
1264 case SHOW_WINDOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001265 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 handleWindowVisibility((IBinder)msg.obj, true);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001267 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 break;
1269 case HIDE_WINDOW:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001270 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 handleWindowVisibility((IBinder)msg.obj, false);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001272 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273 break;
1274 case RESUME_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001275 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276 handleResumeActivity((IBinder)msg.obj, true,
Dianne Hackbornad9b32112012-09-17 15:35:01 -07001277 msg.arg1 != 0, true);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001278 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 break;
1280 case SEND_RESULT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001281 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 handleSendResult((ResultData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001283 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 break;
1285 case DESTROY_ACTIVITY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001286 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1288 msg.arg2, false);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001289 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 break;
1291 case BIND_APPLICATION:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001292 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001293 AppBindData data = (AppBindData)msg.obj;
1294 handleBindApplication(data);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001295 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 break;
1297 case EXIT_APPLICATION:
1298 if (mInitialApplication != null) {
1299 mInitialApplication.onTerminate();
1300 }
1301 Looper.myLooper().quit();
1302 break;
1303 case NEW_INTENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001304 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 handleNewIntent((NewIntentData)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 RECEIVER:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001309 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 handleReceiver((ReceiverData)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 CREATE_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001315 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 handleCreateService((CreateServiceData)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 BIND_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001320 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321 handleBindService((BindServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001322 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 break;
1324 case UNBIND_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001325 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 handleUnbindService((BindServiceData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001327 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 break;
1329 case SERVICE_ARGS:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001330 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331 handleServiceArgs((ServiceArgsData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001332 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 break;
1334 case STOP_SERVICE:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001335 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 handleStopService((IBinder)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001337 maybeSnapshot();
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 REQUEST_THUMBNAIL:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001341 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 handleRequestThumbnail((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;
1345 case CONFIGURATION_CHANGED:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001346 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged");
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001347 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001348 handleConfigurationChanged((Configuration)msg.obj, null);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001349 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001350 break;
1351 case CLEAN_UP_CONTEXT:
1352 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1353 cci.context.performFinalCleanup(cci.who, cci.what);
1354 break;
1355 case GC_WHEN_IDLE:
1356 scheduleGcIdler();
1357 break;
1358 case DUMP_SERVICE:
Dianne Hackborn625ac272010-09-17 18:29:22 -07001359 handleDumpService((DumpComponentInfo)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001360 break;
1361 case LOW_MEMORY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001362 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001363 handleLowMemory();
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001364 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 break;
1366 case ACTIVITY_CONFIGURATION_CHANGED:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001367 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001368 handleActivityConfigurationChanged((IBinder)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001369 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 break;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001371 case PROFILER_CONTROL:
Romain Guy7eabe552011-07-21 14:56:34 -07001372 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001373 break;
Christopher Tate181fafa2009-05-14 11:12:14 -07001374 case CREATE_BACKUP_AGENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001375 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -07001376 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001377 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate181fafa2009-05-14 11:12:14 -07001378 break;
1379 case DESTROY_BACKUP_AGENT:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001380 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent");
Christopher Tate181fafa2009-05-14 11:12:14 -07001381 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001382 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate181fafa2009-05-14 11:12:14 -07001383 break;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001384 case SUICIDE:
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001385 Process.killProcess(Process.myPid());
1386 break;
1387 case REMOVE_PROVIDER:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001388 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove");
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001389 completeRemoveProvider((ProviderRefCount)msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001390 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Christopher Tate5e1ab332009-09-01 20:32:49 -07001391 break;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001392 case ENABLE_JIT:
1393 ensureJitEnabled();
1394 break;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001395 case DISPATCH_PACKAGE_BROADCAST:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001396 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001397 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001398 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001399 break;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001400 case SCHEDULE_CRASH:
1401 throw new RemoteServiceException((String)msg.obj);
Andy McFadden824c5102010-07-09 16:26:57 -07001402 case DUMP_HEAP:
1403 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1404 break;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001405 case DUMP_ACTIVITY:
1406 handleDumpActivity((DumpComponentInfo)msg.obj);
1407 break;
Marco Nelissen18cb2872011-11-15 11:19:53 -08001408 case DUMP_PROVIDER:
1409 handleDumpProvider((DumpComponentInfo)msg.obj);
1410 break;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001411 case SLEEPING:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001412 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping");
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001413 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001414 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001415 break;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001416 case SET_CORE_SETTINGS:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001417 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings");
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001418 handleSetCoreSettings((Bundle) msg.obj);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001419 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001420 break;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001421 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1422 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001423 break;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001424 case TRIM_MEMORY:
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001425 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory");
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001426 handleTrimMemory(msg.arg1);
Dianne Hackborn1ded0b12012-04-26 14:14:50 -07001427 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001428 break;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07001429 case UNSTABLE_PROVIDER_DIED:
1430 handleUnstableProviderDied((IBinder)msg.obj, false);
1431 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 }
Dianne Hackborn755c8bf2012-05-07 15:06:09 -07001433 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 }
Bob Leee5408332009-09-04 18:31:17 -07001435
Brian Carlstromed7e0072011-03-24 13:27:57 -07001436 private void maybeSnapshot() {
1437 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
Sen Hubde75702010-05-28 01:54:03 -07001438 // convert the *private* ActivityThread.PackageInfo to *public* known
1439 // android.content.pm.PackageInfo
1440 String packageName = mBoundApplication.info.mPackageName;
1441 android.content.pm.PackageInfo packageInfo = null;
1442 try {
1443 Context context = getSystemContext();
1444 if(context == null) {
1445 Log.e(TAG, "cannot get a valid context");
1446 return;
1447 }
1448 PackageManager pm = context.getPackageManager();
1449 if(pm == null) {
1450 Log.e(TAG, "cannot get a valid PackageManager");
1451 return;
1452 }
1453 packageInfo = pm.getPackageInfo(
1454 packageName, PackageManager.GET_ACTIVITIES);
1455 } catch (NameNotFoundException e) {
1456 Log.e(TAG, "cannot get package info for " + packageName, e);
1457 }
1458 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
Bob Leee5408332009-09-04 18:31:17 -07001459 }
1460 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 }
1462
Romain Guy65b345f2011-07-27 18:51:50 -07001463 private class Idler implements MessageQueue.IdleHandler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 public final boolean queueIdle() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001465 ActivityClientRecord a = mNewActivities;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001466 boolean stopProfiling = false;
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001467 if (mBoundApplication != null && mProfiler.profileFd != null
1468 && mProfiler.autoStopProfiler) {
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001469 stopProfiling = true;
1470 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 if (a != null) {
1472 mNewActivities = null;
1473 IActivityManager am = ActivityManagerNative.getDefault();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001474 ActivityClientRecord prev;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 do {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001476 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001477 TAG, "Reporting idle of " + a +
1478 " finished=" +
Romain Guy65b345f2011-07-27 18:51:50 -07001479 (a.activity != null && a.activity.mFinished));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001480 if (a.activity != null && !a.activity.mFinished) {
1481 try {
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001482 am.activityIdle(a.token, a.createdConfig, stopProfiling);
Dianne Hackborne88846e2009-09-30 21:34:25 -07001483 a.createdConfig = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001484 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07001485 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 }
1487 }
1488 prev = a;
1489 a = a.nextIdle;
1490 prev.nextIdle = null;
1491 } while (a != null);
1492 }
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001493 if (stopProfiling) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001494 mProfiler.stopProfiling();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07001495 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001496 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 return false;
1498 }
1499 }
1500
1501 final class GcIdler implements MessageQueue.IdleHandler {
1502 public final boolean queueIdle() {
1503 doGcIfNeeded();
1504 return false;
1505 }
1506 }
1507
Romain Guy65b345f2011-07-27 18:51:50 -07001508 private static class ResourcesKey {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001509 final private String mResDir;
Jeff Browna492c3a2012-08-23 19:48:44 -07001510 final private int mDisplayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001511 final private Configuration mOverrideConfiguration;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001512 final private float mScale;
1513 final private int mHash;
Bob Leee5408332009-09-04 18:31:17 -07001514
Jeff Browna492c3a2012-08-23 19:48:44 -07001515 ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001516 mResDir = resDir;
Jeff Browna492c3a2012-08-23 19:48:44 -07001517 mDisplayId = displayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001518 if (overrideConfiguration != null) {
1519 if (Configuration.EMPTY.equals(overrideConfiguration)) {
1520 overrideConfiguration = null;
1521 }
1522 }
1523 mOverrideConfiguration = overrideConfiguration;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001524 mScale = scale;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001525 int hash = 17;
1526 hash = 31 * hash + mResDir.hashCode();
Jeff Browna492c3a2012-08-23 19:48:44 -07001527 hash = 31 * hash + mDisplayId;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001528 hash = 31 * hash + (mOverrideConfiguration != null
1529 ? mOverrideConfiguration.hashCode() : 0);
1530 hash = 31 * hash + Float.floatToIntBits(mScale);
1531 mHash = hash;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001532 }
Bob Leee5408332009-09-04 18:31:17 -07001533
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001534 @Override
1535 public int hashCode() {
1536 return mHash;
1537 }
1538
1539 @Override
1540 public boolean equals(Object obj) {
1541 if (!(obj instanceof ResourcesKey)) {
1542 return false;
1543 }
1544 ResourcesKey peer = (ResourcesKey) obj;
Dianne Hackborn756220b2012-08-14 16:45:30 -07001545 if (!mResDir.equals(peer.mResDir)) {
1546 return false;
1547 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001548 if (mDisplayId != peer.mDisplayId) {
1549 return false;
1550 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001551 if (mOverrideConfiguration != peer.mOverrideConfiguration) {
1552 if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) {
1553 return false;
1554 }
1555 if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) {
1556 return false;
1557 }
1558 }
1559 if (mScale != peer.mScale) {
1560 return false;
1561 }
1562 return true;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001563 }
1564 }
1565
Romain Guy65b345f2011-07-27 18:51:50 -07001566 public static ActivityThread currentActivityThread() {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07001567 return sThreadLocal.get();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001568 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001569
Romain Guy65b345f2011-07-27 18:51:50 -07001570 public static String currentPackageName() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001571 ActivityThread am = currentActivityThread();
1572 return (am != null && am.mBoundApplication != null)
1573 ? am.mBoundApplication.processName : null;
1574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575
Romain Guy65b345f2011-07-27 18:51:50 -07001576 public static Application currentApplication() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001577 ActivityThread am = currentActivityThread();
1578 return am != null ? am.mInitialApplication : null;
1579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001581 public static IPackageManager getPackageManager() {
1582 if (sPackageManager != null) {
1583 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1584 return sPackageManager;
1585 }
1586 IBinder b = ServiceManager.getService("package");
1587 //Slog.v("PackageManager", "default service binder = " + b);
1588 sPackageManager = IPackageManager.Stub.asInterface(b);
1589 //Slog.v("PackageManager", "default service = " + sPackageManager);
1590 return sPackageManager;
1591 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592
Jeff Browna492c3a2012-08-23 19:48:44 -07001593 private void flushDisplayMetricsLocked() {
1594 mDefaultDisplayMetrics.clear();
1595 }
1596
1597 DisplayMetrics getDisplayMetricsLocked(int displayId, CompatibilityInfo ci) {
1598 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1599 DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(ci) : null;
1600 if (dm != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001601 return dm;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001602 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001603 dm = new DisplayMetrics();
Jeff Brown848c2dc2012-08-19 20:18:08 -07001604
Jeff Brownbd6e1502012-08-28 03:27:37 -07001605 DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance();
Jeff Brown848c2dc2012-08-19 20:18:08 -07001606 if (displayManager == null) {
1607 // may be null early in system startup
Jeff Brown848c2dc2012-08-19 20:18:08 -07001608 dm.setToDefaults();
1609 return dm;
1610 }
1611
Jeff Browna492c3a2012-08-23 19:48:44 -07001612 if (isDefaultDisplay) {
1613 mDefaultDisplayMetrics.put(ci, dm);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001614 }
Jeff Brown848c2dc2012-08-19 20:18:08 -07001615
Jeff Brownd32460c2012-07-20 16:15:36 -07001616 CompatibilityInfoHolder cih = new CompatibilityInfoHolder();
1617 cih.set(ci);
Jeff Browna492c3a2012-08-23 19:48:44 -07001618 Display d = displayManager.getCompatibleDisplay(displayId, cih);
Jeff Browna3909a92012-09-09 00:57:09 -07001619 if (d != null) {
1620 d.getMetrics(dm);
1621 } else {
1622 // Display no longer exists
1623 // FIXME: This would not be a problem if we kept the Display object around
1624 // instead of using the raw display id everywhere. The Display object caches
1625 // its information even after the display has been removed.
1626 dm.setToDefaults();
1627 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001628 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1629 // + metrics.heightPixels + " den=" + metrics.density
1630 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001631 return dm;
1632 }
1633
Romain Guy65b345f2011-07-27 18:51:50 -07001634 private Configuration mMainThreadConfig = new Configuration();
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001635 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config,
1636 CompatibilityInfo compat) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001637 if (config == null) {
1638 return null;
1639 }
1640 if (compat != null && !compat.supportsScreen()) {
1641 mMainThreadConfig.setTo(config);
1642 config = mMainThreadConfig;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07001643 compat.applyToConfiguration(displayDensity, config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001644 }
1645 return config;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001646 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001647
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001648 /**
1649 * Creates the top level Resources for applications with the given compatibility info.
1650 *
1651 * @param resDir the resource directory.
1652 * @param compInfo the compability info. It will use the default compatibility info when it's
1653 * null.
1654 */
Jeff Browna492c3a2012-08-23 19:48:44 -07001655 Resources getTopLevelResources(String resDir,
1656 int displayId, Configuration overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001657 CompatibilityInfo compInfo) {
Jeff Browna492c3a2012-08-23 19:48:44 -07001658 ResourcesKey key = new ResourcesKey(resDir,
1659 displayId, overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001660 compInfo.applicationScale);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001661 Resources r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001662 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001663 // Resources is app scale dependent.
1664 if (false) {
1665 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1666 + compInfo.applicationScale);
1667 }
1668 WeakReference<Resources> wr = mActiveResources.get(key);
1669 r = wr != null ? wr.get() : null;
1670 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1671 if (r != null && r.getAssets().isUpToDate()) {
1672 if (false) {
1673 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1674 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1675 }
1676 return r;
1677 }
1678 }
1679
1680 //if (r != null) {
1681 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1682 // + r + " " + resDir);
1683 //}
1684
1685 AssetManager assets = new AssetManager();
1686 if (assets.addAssetPath(resDir) == 0) {
1687 return null;
1688 }
1689
1690 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
Jeff Browna492c3a2012-08-23 19:48:44 -07001691 DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
Dianne Hackborn756220b2012-08-14 16:45:30 -07001692 Configuration config;
Jeff Browna492c3a2012-08-23 19:48:44 -07001693 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
1694 if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07001695 config = new Configuration(getConfiguration());
Jeff Browna492c3a2012-08-23 19:48:44 -07001696 if (!isDefaultDisplay) {
1697 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
1698 }
1699 if (key.mOverrideConfiguration != null) {
1700 config.updateFrom(key.mOverrideConfiguration);
1701 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001702 } else {
1703 config = getConfiguration();
1704 }
Jeff Browna492c3a2012-08-23 19:48:44 -07001705 r = new Resources(assets, dm, config, compInfo);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001706 if (false) {
1707 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1708 + r.getConfiguration() + " appScale="
1709 + r.getCompatibilityInfo().applicationScale);
1710 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07001711
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001712 synchronized (mPackages) {
1713 WeakReference<Resources> wr = mActiveResources.get(key);
1714 Resources existing = wr != null ? wr.get() : null;
1715 if (existing != null && existing.getAssets().isUpToDate()) {
1716 // Someone else already created the resources while we were
1717 // unlocked; go ahead and use theirs.
1718 r.getAssets().close();
1719 return existing;
1720 }
1721
1722 // XXX need to remove entries when weak references go away
1723 mActiveResources.put(key, new WeakReference<Resources>(r));
1724 return r;
1725 }
1726 }
1727
1728 /**
1729 * Creates the top level resources for the given package.
1730 */
Jeff Browna492c3a2012-08-23 19:48:44 -07001731 Resources getTopLevelResources(String resDir,
1732 int displayId, Configuration overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001733 LoadedApk pkgInfo) {
Jeff Browna492c3a2012-08-23 19:48:44 -07001734 return getTopLevelResources(resDir, displayId, overrideConfiguration,
Dianne Hackborn756220b2012-08-14 16:45:30 -07001735 pkgInfo.mCompatibilityInfo.get());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001736 }
1737
1738 final Handler getHandler() {
1739 return mH;
1740 }
1741
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001742 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1743 int flags) {
Amith Yamasani98edc952012-09-25 14:09:27 -07001744 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId());
1745 }
1746
1747 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1748 int flags, int userId) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001749 synchronized (mPackages) {
1750 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001751 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1752 ref = mPackages.get(packageName);
1753 } else {
1754 ref = mResourcePackages.get(packageName);
1755 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001756 LoadedApk packageInfo = ref != null ? ref.get() : null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001757 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001758 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1759 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001760 if (packageInfo != null && (packageInfo.mResources == null
1761 || packageInfo.mResources.getAssets().isUpToDate())) {
1762 if (packageInfo.isSecurityViolation()
1763 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1764 throw new SecurityException(
1765 "Requesting code from " + packageName
1766 + " to be run in process "
1767 + mBoundApplication.processName
1768 + "/" + mBoundApplication.appInfo.uid);
1769 }
1770 return packageInfo;
1771 }
1772 }
1773
1774 ApplicationInfo ai = null;
1775 try {
1776 ai = getPackageManager().getApplicationInfo(packageName,
Amith Yamasani98edc952012-09-25 14:09:27 -07001777 PackageManager.GET_SHARED_LIBRARY_FILES, userId);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001778 } catch (RemoteException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07001779 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 }
1781
1782 if (ai != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001783 return getPackageInfo(ai, compatInfo, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001784 }
1785
1786 return null;
1787 }
1788
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001789 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1790 int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1792 boolean securityViolation = includeCode && ai.uid != 0
1793 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07001794 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid)
Amith Yamasani742a6712011-05-04 14:49:28 -07001795 : true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001796 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1797 |Context.CONTEXT_IGNORE_SECURITY))
1798 == Context.CONTEXT_INCLUDE_CODE) {
1799 if (securityViolation) {
1800 String msg = "Requesting code from " + ai.packageName
1801 + " (with uid " + ai.uid + ")";
1802 if (mBoundApplication != null) {
1803 msg = msg + " to be run in process "
1804 + mBoundApplication.processName + " (with uid "
1805 + mBoundApplication.appInfo.uid + ")";
1806 }
1807 throw new SecurityException(msg);
1808 }
1809 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001810 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001811 }
1812
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001813 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1814 CompatibilityInfo compatInfo) {
1815 return getPackageInfo(ai, compatInfo, null, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001816 }
1817
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001818 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1819 synchronized (mPackages) {
1820 WeakReference<LoadedApk> ref;
1821 if (includeCode) {
1822 ref = mPackages.get(packageName);
1823 } else {
1824 ref = mResourcePackages.get(packageName);
1825 }
1826 return ref != null ? ref.get() : null;
1827 }
1828 }
1829
Romain Guy65b345f2011-07-27 18:51:50 -07001830 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001831 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1832 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001833 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001834 if (includeCode) {
1835 ref = mPackages.get(aInfo.packageName);
1836 } else {
1837 ref = mResourcePackages.get(aInfo.packageName);
1838 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001839 LoadedApk packageInfo = ref != null ? ref.get() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 if (packageInfo == null || (packageInfo.mResources != null
1841 && !packageInfo.mResources.getAssets().isUpToDate())) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001842 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 : "Loading resource-only package ") + aInfo.packageName
1844 + " (in " + (mBoundApplication != null
1845 ? mBoundApplication.processName : null)
1846 + ")");
1847 packageInfo =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001848 new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 securityViolation, includeCode &&
1850 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1851 if (includeCode) {
1852 mPackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001853 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001854 } else {
1855 mResourcePackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001856 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001857 }
1858 }
1859 return packageInfo;
1860 }
1861 }
1862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 ActivityThread() {
1864 }
1865
1866 public ApplicationThread getApplicationThread()
1867 {
1868 return mAppThread;
1869 }
1870
1871 public Instrumentation getInstrumentation()
1872 {
1873 return mInstrumentation;
1874 }
1875
1876 public Configuration getConfiguration() {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001877 return mResConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 }
1879
1880 public boolean isProfiling() {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001881 return mProfiler != null && mProfiler.profileFile != null
1882 && mProfiler.profileFd == null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001883 }
1884
1885 public String getProfileFilePath() {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001886 return mProfiler.profileFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001887 }
1888
1889 public Looper getLooper() {
1890 return mLooper;
1891 }
1892
1893 public Application getApplication() {
1894 return mInitialApplication;
1895 }
Bob Leee5408332009-09-04 18:31:17 -07001896
Dianne Hackbornd97c7ad2009-06-19 11:37:35 -07001897 public String getProcessName() {
1898 return mBoundApplication.processName;
1899 }
Bob Leee5408332009-09-04 18:31:17 -07001900
Dianne Hackborn21556372010-02-04 16:34:40 -08001901 public ContextImpl getSystemContext() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001902 synchronized (this) {
1903 if (mSystemContext == null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001904 ContextImpl context =
1905 ContextImpl.createSystemContext(this);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001906 LoadedApk info = new LoadedApk(this, "android", context, null,
1907 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001908 context.init(info, null, this);
1909 context.getResources().updateConfiguration(
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001910 getConfiguration(), getDisplayMetricsLocked(
Jeff Browna492c3a2012-08-23 19:48:44 -07001911 Display.DEFAULT_DISPLAY,
1912 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001913 mSystemContext = context;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001914 //Slog.i(TAG, "Created system resources " + context.getResources()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 // + ": " + context.getResources().getConfiguration());
1916 }
1917 }
1918 return mSystemContext;
1919 }
1920
Mike Cleron432b7132009-09-24 15:28:29 -07001921 public void installSystemApplicationInfo(ApplicationInfo info) {
1922 synchronized (this) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001923 ContextImpl context = getSystemContext();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001924 context.init(new LoadedApk(this, "android", context, info,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001925 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07001926
1927 // give ourselves a default profiler
1928 mProfiler = new Profiler();
Mike Cleron432b7132009-09-24 15:28:29 -07001929 }
1930 }
1931
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001932 void ensureJitEnabled() {
1933 if (!mJitEnabled) {
1934 mJitEnabled = true;
1935 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1936 }
1937 }
1938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001939 void scheduleGcIdler() {
1940 if (!mGcIdlerScheduled) {
1941 mGcIdlerScheduled = true;
1942 Looper.myQueue().addIdleHandler(mGcIdler);
1943 }
1944 mH.removeMessages(H.GC_WHEN_IDLE);
1945 }
1946
1947 void unscheduleGcIdler() {
1948 if (mGcIdlerScheduled) {
1949 mGcIdlerScheduled = false;
1950 Looper.myQueue().removeIdleHandler(mGcIdler);
1951 }
1952 mH.removeMessages(H.GC_WHEN_IDLE);
1953 }
1954
1955 void doGcIfNeeded() {
1956 mGcIdlerScheduled = false;
1957 final long now = SystemClock.uptimeMillis();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001958 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 // + "m now=" + now);
1960 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001961 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001962 BinderInternal.forceGc("bg");
1963 }
1964 }
1965
Jeff Hamilton52d32032011-01-08 15:31:26 -06001966 public void registerOnActivityPausedListener(Activity activity,
1967 OnActivityPausedListener listener) {
1968 synchronized (mOnPauseListeners) {
1969 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1970 if (list == null) {
1971 list = new ArrayList<OnActivityPausedListener>();
1972 mOnPauseListeners.put(activity, list);
1973 }
1974 list.add(listener);
1975 }
1976 }
1977
Jeff Hamiltonce3224c2011-01-17 11:05:03 -08001978 public void unregisterOnActivityPausedListener(Activity activity,
1979 OnActivityPausedListener listener) {
1980 synchronized (mOnPauseListeners) {
1981 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1982 if (list != null) {
1983 list.remove(listener);
1984 }
1985 }
1986 }
1987
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001988 public final ActivityInfo resolveActivityInfo(Intent intent) {
1989 ActivityInfo aInfo = intent.resolveActivityInfo(
1990 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
1991 if (aInfo == null) {
1992 // Throw an exception.
1993 Instrumentation.checkStartActivityResult(
Dianne Hackborna4972e92012-03-14 10:38:05 -07001994 ActivityManager.START_CLASS_NOT_FOUND, intent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001995 }
1996 return aInfo;
1997 }
Bob Leee5408332009-09-04 18:31:17 -07001998
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 public final Activity startActivityNow(Activity parent, String id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002000 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002001 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002002 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002004 r.ident = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002005 r.intent = intent;
2006 r.state = state;
2007 r.parent = parent;
2008 r.embeddedID = id;
2009 r.activityInfo = activityInfo;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002010 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002011 if (localLOGV) {
2012 ComponentName compname = intent.getComponent();
2013 String name;
2014 if (compname != null) {
2015 name = compname.toShortString();
2016 } else {
2017 name = "(Intent " + intent + ").getComponent() returned null";
2018 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002019 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002020 + ", comp=" + name
2021 + ", token=" + token);
2022 }
Christopher Tateb70f3df2009-04-07 16:07:59 -07002023 return performLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002024 }
2025
2026 public final Activity getActivity(IBinder token) {
2027 return mActivities.get(token).activity;
2028 }
2029
2030 public final void sendActivityResult(
2031 IBinder token, String id, int requestCode,
2032 int resultCode, Intent data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002033 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
Chris Tate8a7dc172009-03-24 20:11:42 -07002034 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002035 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
2036 list.add(new ResultInfo(id, requestCode, resultCode, data));
2037 mAppThread.scheduleSendResult(token, list);
2038 }
2039
2040 // if the thread hasn't started yet, we don't have the handler, so just
2041 // save the messages until we're ready.
Romain Guy65b345f2011-07-27 18:51:50 -07002042 private void queueOrSendMessage(int what, Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002043 queueOrSendMessage(what, obj, 0, 0);
2044 }
2045
Romain Guy65b345f2011-07-27 18:51:50 -07002046 private void queueOrSendMessage(int what, Object obj, int arg1) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002047 queueOrSendMessage(what, obj, arg1, 0);
2048 }
2049
Romain Guy65b345f2011-07-27 18:51:50 -07002050 private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002051 synchronized (this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07002052 if (DEBUG_MESSAGES) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002053 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
2054 + ": " + arg1 + " / " + obj);
2055 Message msg = Message.obtain();
2056 msg.what = what;
2057 msg.obj = obj;
2058 msg.arg1 = arg1;
2059 msg.arg2 = arg2;
2060 mH.sendMessage(msg);
2061 }
2062 }
2063
Dianne Hackborn21556372010-02-04 16:34:40 -08002064 final void scheduleContextCleanup(ContextImpl context, String who,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002065 String what) {
2066 ContextCleanupInfo cci = new ContextCleanupInfo();
2067 cci.context = context;
2068 cci.who = who;
2069 cci.what = what;
2070 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
2071 }
2072
Romain Guy65b345f2011-07-27 18:51:50 -07002073 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002074 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
2075
2076 ActivityInfo aInfo = r.activityInfo;
2077 if (r.packageInfo == null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002078 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002079 Context.CONTEXT_INCLUDE_CODE);
2080 }
Bob Leee5408332009-09-04 18:31:17 -07002081
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002082 ComponentName component = r.intent.getComponent();
2083 if (component == null) {
2084 component = r.intent.resolveActivity(
2085 mInitialApplication.getPackageManager());
2086 r.intent.setComponent(component);
2087 }
2088
2089 if (r.activityInfo.targetActivity != null) {
2090 component = new ComponentName(r.activityInfo.packageName,
2091 r.activityInfo.targetActivity);
2092 }
2093
2094 Activity activity = null;
2095 try {
2096 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
2097 activity = mInstrumentation.newActivity(
2098 cl, component.getClassName(), r.intent);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002099 StrictMode.incrementExpectedActivityCount(activity.getClass());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002100 r.intent.setExtrasClassLoader(cl);
2101 if (r.state != null) {
2102 r.state.setClassLoader(cl);
2103 }
2104 } catch (Exception e) {
2105 if (!mInstrumentation.onException(activity, e)) {
2106 throw new RuntimeException(
2107 "Unable to instantiate activity " + component
2108 + ": " + e.toString(), e);
2109 }
2110 }
2111
2112 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002113 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07002114
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002115 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2116 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 TAG, r + ": app=" + app
2118 + ", appName=" + app.getPackageName()
2119 + ", pkg=" + r.packageInfo.getPackageName()
2120 + ", comp=" + r.intent.getComponent().toShortString()
2121 + ", dir=" + r.packageInfo.getAppDir());
2122
2123 if (activity != null) {
Jeff Brownefd43bd2012-09-21 17:02:35 -07002124 Context appContext = createBaseContextForActivity(r, activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002126 Configuration config = new Configuration(mCompatConfiguration);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002127 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002128 + r.activityInfo.name + " with config " + config);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07002129 activity.attach(appContext, this, getInstrumentation(), r.token,
2130 r.ident, app, r.intent, r.activityInfo, title, r.parent,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002131 r.embeddedID, r.lastNonConfigurationInstances, config);
Bob Leee5408332009-09-04 18:31:17 -07002132
Christopher Tateb70f3df2009-04-07 16:07:59 -07002133 if (customIntent != null) {
2134 activity.mIntent = customIntent;
2135 }
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002136 r.lastNonConfigurationInstances = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 activity.mStartedActivity = false;
2138 int theme = r.activityInfo.getThemeResource();
2139 if (theme != 0) {
2140 activity.setTheme(theme);
2141 }
2142
2143 activity.mCalled = false;
2144 mInstrumentation.callActivityOnCreate(activity, r.state);
2145 if (!activity.mCalled) {
2146 throw new SuperNotCalledException(
2147 "Activity " + r.intent.getComponent().toShortString() +
2148 " did not call through to super.onCreate()");
2149 }
2150 r.activity = activity;
2151 r.stopped = true;
2152 if (!r.activity.mFinished) {
2153 activity.performStart();
2154 r.stopped = false;
2155 }
2156 if (!r.activity.mFinished) {
2157 if (r.state != null) {
2158 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
2159 }
2160 }
2161 if (!r.activity.mFinished) {
2162 activity.mCalled = false;
2163 mInstrumentation.callActivityOnPostCreate(activity, r.state);
2164 if (!activity.mCalled) {
2165 throw new SuperNotCalledException(
2166 "Activity " + r.intent.getComponent().toShortString() +
2167 " did not call through to super.onPostCreate()");
2168 }
2169 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170 }
2171 r.paused = true;
2172
2173 mActivities.put(r.token, r);
2174
2175 } catch (SuperNotCalledException e) {
2176 throw e;
2177
2178 } catch (Exception e) {
2179 if (!mInstrumentation.onException(activity, e)) {
2180 throw new RuntimeException(
2181 "Unable to start activity " + component
2182 + ": " + e.toString(), e);
2183 }
2184 }
2185
2186 return activity;
2187 }
2188
Jeff Brownefd43bd2012-09-21 17:02:35 -07002189 private Context createBaseContextForActivity(ActivityClientRecord r,
2190 final Activity activity) {
2191 ContextImpl appContext = new ContextImpl();
2192 appContext.init(r.packageInfo, r.token, this);
2193 appContext.setOuterContext(activity);
2194
2195 // For debugging purposes, if the activity's package name contains the value of
2196 // the "debug.use-second-display" system property as a substring, then show
2197 // its content on a secondary display if there is one.
2198 Context baseContext = appContext;
2199 String pkgName = SystemProperties.get("debug.second-display.pkg");
2200 if (pkgName != null && !pkgName.isEmpty()
2201 && r.packageInfo.mPackageName.contains(pkgName)) {
2202 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance();
2203 for (int displayId : dm.getDisplayIds()) {
2204 if (displayId != Display.DEFAULT_DISPLAY) {
2205 Display display = dm.getRealDisplay(displayId);
2206 baseContext = appContext.createDisplayContext(display);
2207 break;
2208 }
2209 }
2210 }
2211 return baseContext;
2212 }
2213
Romain Guy65b345f2011-07-27 18:51:50 -07002214 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 // If we are getting ready to gc after going to the background, well
2216 // we are back active so skip it.
2217 unscheduleGcIdler();
2218
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002219 if (r.profileFd != null) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07002220 mProfiler.setProfiler(r.profileFile, r.profileFd);
2221 mProfiler.startProfiling();
2222 mProfiler.autoStopProfiler = r.autoStopProfiler;
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07002223 }
2224
Dianne Hackborn58f42a52011-10-10 13:46:34 -07002225 // Make sure we are running with the most recent config.
2226 handleConfigurationChanged(null, null);
2227
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002228 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002229 TAG, "Handling launch of " + r);
Christopher Tateb70f3df2009-04-07 16:07:59 -07002230 Activity a = performLaunchActivity(r, customIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002231
2232 if (a != null) {
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08002233 r.createdConfig = new Configuration(mConfiguration);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002234 Bundle oldState = r.state;
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002235 handleResumeActivity(r.token, false, r.isForward,
2236 !r.activity.mFinished && !r.startsNotResumed);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002237
2238 if (!r.activity.mFinished && r.startsNotResumed) {
2239 // The activity manager actually wants this one to start out
2240 // paused, because it needs to be visible but isn't in the
2241 // foreground. We accomplish this by going through the
2242 // normal startup (because activities expect to go through
2243 // onResume() the first time they run, before their window
2244 // is displayed), and then pausing it. However, in this case
2245 // we do -not- need to do the full pause cycle (of freezing
2246 // and such) because the activity manager assumes it can just
2247 // retain the current state it has.
2248 try {
2249 r.activity.mCalled = false;
2250 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08002251 // We need to keep around the original state, in case
Dianne Hackborn03fcc332012-05-15 12:49:40 -07002252 // we need to be created again. But we only do this
2253 // for pre-Honeycomb apps, which always save their state
2254 // when pausing, so we can not have them save their state
2255 // when restarting from a paused state. For HC and later,
2256 // we want to (and can) let the state be saved as the normal
2257 // part of stopping the activity.
2258 if (r.isPreHoneycomb()) {
2259 r.state = oldState;
2260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 if (!r.activity.mCalled) {
2262 throw new SuperNotCalledException(
2263 "Activity " + r.intent.getComponent().toShortString() +
2264 " did not call through to super.onPause()");
2265 }
2266
2267 } catch (SuperNotCalledException e) {
2268 throw e;
2269
2270 } catch (Exception e) {
2271 if (!mInstrumentation.onException(r.activity, e)) {
2272 throw new RuntimeException(
2273 "Unable to pause activity "
2274 + r.intent.getComponent().toShortString()
2275 + ": " + e.toString(), e);
2276 }
2277 }
2278 r.paused = true;
2279 }
2280 } else {
2281 // If there was an error, for any reason, tell the activity
2282 // manager to stop us.
2283 try {
2284 ActivityManagerNative.getDefault()
2285 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
2286 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07002287 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 }
2289 }
2290 }
2291
Romain Guy65b345f2011-07-27 18:51:50 -07002292 private void deliverNewIntents(ActivityClientRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 List<Intent> intents) {
2294 final int N = intents.size();
2295 for (int i=0; i<N; i++) {
2296 Intent intent = intents.get(i);
2297 intent.setExtrasClassLoader(r.activity.getClassLoader());
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002298 r.activity.mFragments.noteStateNotSaved();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
2300 }
2301 }
2302
2303 public final void performNewIntents(IBinder token,
2304 List<Intent> intents) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002305 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 if (r != null) {
2307 final boolean resumed = !r.paused;
2308 if (resumed) {
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002309 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002310 mInstrumentation.callActivityOnPause(r.activity);
2311 }
2312 deliverNewIntents(r, intents);
2313 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07002314 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002315 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 }
2317 }
2318 }
Bob Leee5408332009-09-04 18:31:17 -07002319
Romain Guy65b345f2011-07-27 18:51:50 -07002320 private void handleNewIntent(NewIntentData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 performNewIntents(data.token, data.intents);
2322 }
2323
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002324 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
2325
2326 /**
2327 * Return the Intent that's currently being handled by a
2328 * BroadcastReceiver on this thread, or null if none.
2329 * @hide
2330 */
2331 public static Intent getIntentBeingBroadcast() {
2332 return sCurrentBroadcastIntent.get();
2333 }
2334
Romain Guy65b345f2011-07-27 18:51:50 -07002335 private void handleReceiver(ReceiverData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002336 // If we are getting ready to gc after going to the background, well
2337 // we are back active so skip it.
2338 unscheduleGcIdler();
2339
2340 String component = data.intent.getComponent().getClassName();
2341
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002342 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002343 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002344
2345 IActivityManager mgr = ActivityManagerNative.getDefault();
2346
Romain Guy65b345f2011-07-27 18:51:50 -07002347 BroadcastReceiver receiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002348 try {
2349 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2350 data.intent.setExtrasClassLoader(cl);
Dianne Hackborne829fef2010-10-26 17:44:01 -07002351 data.setExtrasClassLoader(cl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002352 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
2353 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07002354 if (DEBUG_BROADCAST) Slog.i(TAG,
2355 "Finishing failed broadcast to " + data.intent.getComponent());
2356 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 throw new RuntimeException(
2358 "Unable to instantiate receiver " + component
2359 + ": " + e.toString(), e);
2360 }
2361
2362 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002363 Application app = packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07002364
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002365 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002366 TAG, "Performing receive of " + data.intent
2367 + ": app=" + app
2368 + ", appName=" + app.getPackageName()
2369 + ", pkg=" + packageInfo.getPackageName()
2370 + ", comp=" + data.intent.getComponent().toShortString()
2371 + ", dir=" + packageInfo.getAppDir());
2372
Dianne Hackborn21556372010-02-04 16:34:40 -08002373 ContextImpl context = (ContextImpl)app.getBaseContext();
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002374 sCurrentBroadcastIntent.set(data.intent);
Dianne Hackborne829fef2010-10-26 17:44:01 -07002375 receiver.setPendingResult(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002376 receiver.onReceive(context.getReceiverRestrictedContext(),
2377 data.intent);
2378 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07002379 if (DEBUG_BROADCAST) Slog.i(TAG,
2380 "Finishing failed broadcast to " + data.intent.getComponent());
2381 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002382 if (!mInstrumentation.onException(receiver, e)) {
2383 throw new RuntimeException(
2384 "Unable to start receiver " + component
2385 + ": " + e.toString(), e);
2386 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002387 } finally {
2388 sCurrentBroadcastIntent.set(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 }
2390
Dianne Hackborne829fef2010-10-26 17:44:01 -07002391 if (receiver.getPendingResult() != null) {
2392 data.finish();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002393 }
2394 }
2395
Christopher Tate181fafa2009-05-14 11:12:14 -07002396 // Instantiate a BackupAgent and tell it that it's alive
Romain Guy65b345f2011-07-27 18:51:50 -07002397 private void handleCreateBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002398 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002399
Christopher Tate346acb12012-10-15 19:20:25 -07002400 // Sanity check the requested target package's uid against ours
2401 try {
2402 PackageInfo requestedPackage = getPackageManager().getPackageInfo(
2403 data.appInfo.packageName, 0, UserHandle.myUserId());
2404 if (requestedPackage.applicationInfo.uid != Process.myUid()) {
2405 Slog.w(TAG, "Asked to instantiate non-matching package "
2406 + data.appInfo.packageName);
2407 return;
2408 }
2409 } catch (RemoteException e) {
2410 Slog.e(TAG, "Can't reach package manager", e);
2411 return;
2412 }
2413
Christopher Tate181fafa2009-05-14 11:12:14 -07002414 // no longer idle; we have backup work to do
2415 unscheduleGcIdler();
2416
2417 // instantiate the BackupAgent class named in the manifest
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002418 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002419 String packageName = packageInfo.mPackageName;
Christopher Tate346acb12012-10-15 19:20:25 -07002420 if (packageName == null) {
2421 Slog.d(TAG, "Asked to create backup agent for nonexistent package");
2422 return;
2423 }
2424
Christopher Tate181fafa2009-05-14 11:12:14 -07002425 if (mBackupAgents.get(packageName) != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002426 Slog.d(TAG, "BackupAgent " + " for " + packageName
Christopher Tate181fafa2009-05-14 11:12:14 -07002427 + " already exists");
2428 return;
2429 }
Bob Leee5408332009-09-04 18:31:17 -07002430
Christopher Tate181fafa2009-05-14 11:12:14 -07002431 BackupAgent agent = null;
2432 String classname = data.appInfo.backupAgentName;
Christopher Tate4a627c72011-04-01 14:43:32 -07002433
Christopher Tate79ec80d2011-06-24 14:58:49 -07002434 // full backup operation but no app-supplied agent? use the default implementation
2435 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2436 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
Christopher Tate4a627c72011-04-01 14:43:32 -07002437 classname = "android.app.backup.FullBackupAgent";
Christopher Tate181fafa2009-05-14 11:12:14 -07002438 }
Christopher Tate4a627c72011-04-01 14:43:32 -07002439
Christopher Tate181fafa2009-05-14 11:12:14 -07002440 try {
Christopher Tated1475e02009-07-09 15:36:17 -07002441 IBinder binder = null;
2442 try {
Christopher Tate4a627c72011-04-01 14:43:32 -07002443 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2444
Christopher Tated1475e02009-07-09 15:36:17 -07002445 java.lang.ClassLoader cl = packageInfo.getClassLoader();
Christopher Tate4a627c72011-04-01 14:43:32 -07002446 agent = (BackupAgent) cl.loadClass(classname).newInstance();
Christopher Tated1475e02009-07-09 15:36:17 -07002447
2448 // set up the agent's context
Dianne Hackborn21556372010-02-04 16:34:40 -08002449 ContextImpl context = new ContextImpl();
Christopher Tated1475e02009-07-09 15:36:17 -07002450 context.init(packageInfo, null, this);
2451 context.setOuterContext(agent);
2452 agent.attach(context);
2453
2454 agent.onCreate();
2455 binder = agent.onBind();
2456 mBackupAgents.put(packageName, agent);
2457 } catch (Exception e) {
2458 // If this is during restore, fail silently; otherwise go
2459 // ahead and let the user see the crash.
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002460 Slog.e(TAG, "Agent threw during creation: " + e);
Christopher Tate75a99702011-05-18 16:28:19 -07002461 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2462 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
Christopher Tated1475e02009-07-09 15:36:17 -07002463 throw e;
2464 }
2465 // falling through with 'binder' still null
2466 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002467
2468 // tell the OS that we're live now
Christopher Tate181fafa2009-05-14 11:12:14 -07002469 try {
2470 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2471 } catch (RemoteException e) {
2472 // nothing to do.
2473 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002474 } catch (Exception e) {
2475 throw new RuntimeException("Unable to create BackupAgent "
Christopher Tate4a627c72011-04-01 14:43:32 -07002476 + classname + ": " + e.toString(), e);
Christopher Tate181fafa2009-05-14 11:12:14 -07002477 }
2478 }
2479
2480 // Tear down a BackupAgent
Romain Guy65b345f2011-07-27 18:51:50 -07002481 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002482 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
Bob Leee5408332009-09-04 18:31:17 -07002483
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002484 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002485 String packageName = packageInfo.mPackageName;
2486 BackupAgent agent = mBackupAgents.get(packageName);
2487 if (agent != null) {
2488 try {
2489 agent.onDestroy();
2490 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002491 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002492 e.printStackTrace();
2493 }
2494 mBackupAgents.remove(packageName);
2495 } else {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002496 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002497 }
2498 }
2499
Romain Guy65b345f2011-07-27 18:51:50 -07002500 private void handleCreateService(CreateServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002501 // If we are getting ready to gc after going to the background, well
2502 // we are back active so skip it.
2503 unscheduleGcIdler();
2504
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002505 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002506 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002507 Service service = null;
2508 try {
2509 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2510 service = (Service) cl.loadClass(data.info.name).newInstance();
2511 } catch (Exception e) {
2512 if (!mInstrumentation.onException(service, e)) {
2513 throw new RuntimeException(
2514 "Unable to instantiate service " + data.info.name
2515 + ": " + e.toString(), e);
2516 }
2517 }
2518
2519 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002520 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002521
Dianne Hackborn21556372010-02-04 16:34:40 -08002522 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 context.init(packageInfo, null, this);
2524
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002525 Application app = packageInfo.makeApplication(false, mInstrumentation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 context.setOuterContext(service);
2527 service.attach(context, this, data.info.name, data.token, app,
2528 ActivityManagerNative.getDefault());
2529 service.onCreate();
2530 mServices.put(data.token, service);
2531 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002532 ActivityManagerNative.getDefault().serviceDoneExecuting(
2533 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 } catch (RemoteException e) {
2535 // nothing to do.
2536 }
2537 } catch (Exception e) {
2538 if (!mInstrumentation.onException(service, e)) {
2539 throw new RuntimeException(
2540 "Unable to create service " + data.info.name
2541 + ": " + e.toString(), e);
2542 }
2543 }
2544 }
2545
Romain Guy65b345f2011-07-27 18:51:50 -07002546 private void handleBindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002547 Service s = mServices.get(data.token);
Amith Yamasani742a6712011-05-04 14:49:28 -07002548 if (DEBUG_SERVICE)
2549 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002550 if (s != null) {
2551 try {
2552 data.intent.setExtrasClassLoader(s.getClassLoader());
2553 try {
2554 if (!data.rebind) {
2555 IBinder binder = s.onBind(data.intent);
2556 ActivityManagerNative.getDefault().publishService(
2557 data.token, data.intent, binder);
2558 } else {
2559 s.onRebind(data.intent);
2560 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002561 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002562 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002563 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002564 } catch (RemoteException ex) {
2565 }
2566 } catch (Exception e) {
2567 if (!mInstrumentation.onException(s, e)) {
2568 throw new RuntimeException(
2569 "Unable to bind to service " + s
2570 + " with " + data.intent + ": " + e.toString(), e);
2571 }
2572 }
2573 }
2574 }
2575
Romain Guy65b345f2011-07-27 18:51:50 -07002576 private void handleUnbindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002577 Service s = mServices.get(data.token);
2578 if (s != null) {
2579 try {
2580 data.intent.setExtrasClassLoader(s.getClassLoader());
2581 boolean doRebind = s.onUnbind(data.intent);
2582 try {
2583 if (doRebind) {
2584 ActivityManagerNative.getDefault().unbindFinished(
2585 data.token, data.intent, doRebind);
2586 } else {
2587 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002588 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002589 }
2590 } catch (RemoteException ex) {
2591 }
2592 } catch (Exception e) {
2593 if (!mInstrumentation.onException(s, e)) {
2594 throw new RuntimeException(
2595 "Unable to unbind to service " + s
2596 + " with " + data.intent + ": " + e.toString(), e);
2597 }
2598 }
2599 }
2600 }
2601
Dianne Hackborn625ac272010-09-17 18:29:22 -07002602 private void handleDumpService(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002603 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2604 try {
2605 Service s = mServices.get(info.token);
2606 if (s != null) {
2607 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2608 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2609 pw.flush();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002610 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002611 } finally {
2612 IoUtils.closeQuietly(info.fd);
2613 StrictMode.setThreadPolicy(oldPolicy);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 }
2615 }
2616
Dianne Hackborn625ac272010-09-17 18:29:22 -07002617 private void handleDumpActivity(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002618 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2619 try {
2620 ActivityClientRecord r = mActivities.get(info.token);
2621 if (r != null && r.activity != null) {
2622 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2623 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2624 pw.flush();
Dianne Hackborn625ac272010-09-17 18:29:22 -07002625 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002626 } finally {
2627 IoUtils.closeQuietly(info.fd);
2628 StrictMode.setThreadPolicy(oldPolicy);
Dianne Hackborn625ac272010-09-17 18:29:22 -07002629 }
2630 }
2631
Marco Nelissen18cb2872011-11-15 11:19:53 -08002632 private void handleDumpProvider(DumpComponentInfo info) {
Jeff Sharkeye861b422012-03-01 20:59:22 -08002633 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
2634 try {
2635 ProviderClientRecord r = mLocalProviders.get(info.token);
2636 if (r != null && r.mLocalProvider != null) {
2637 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2638 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args);
2639 pw.flush();
Marco Nelissen18cb2872011-11-15 11:19:53 -08002640 }
Jeff Sharkeye861b422012-03-01 20:59:22 -08002641 } finally {
2642 IoUtils.closeQuietly(info.fd);
2643 StrictMode.setThreadPolicy(oldPolicy);
Marco Nelissen18cb2872011-11-15 11:19:53 -08002644 }
2645 }
2646
Romain Guy65b345f2011-07-27 18:51:50 -07002647 private void handleServiceArgs(ServiceArgsData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002648 Service s = mServices.get(data.token);
2649 if (s != null) {
2650 try {
2651 if (data.args != null) {
2652 data.args.setExtrasClassLoader(s.getClassLoader());
2653 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002654 int res;
2655 if (!data.taskRemoved) {
2656 res = s.onStartCommand(data.args, data.flags, data.startId);
2657 } else {
2658 s.onTaskRemoved(data.args);
2659 res = Service.START_TASK_REMOVED_COMPLETE;
2660 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002661
2662 QueuedWork.waitToFinish();
2663
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002665 ActivityManagerNative.getDefault().serviceDoneExecuting(
2666 data.token, 1, data.startId, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002667 } catch (RemoteException e) {
2668 // nothing to do.
2669 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002670 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 } catch (Exception e) {
2672 if (!mInstrumentation.onException(s, e)) {
2673 throw new RuntimeException(
2674 "Unable to start service " + s
2675 + " with " + data.args + ": " + e.toString(), e);
2676 }
2677 }
2678 }
2679 }
2680
Romain Guy65b345f2011-07-27 18:51:50 -07002681 private void handleStopService(IBinder token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002682 Service s = mServices.remove(token);
2683 if (s != null) {
2684 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002685 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 s.onDestroy();
2687 Context context = s.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002688 if (context instanceof ContextImpl) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002689 final String who = s.getClassName();
Dianne Hackborn21556372010-02-04 16:34:40 -08002690 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002691 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002692
2693 QueuedWork.waitToFinish();
2694
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002696 ActivityManagerNative.getDefault().serviceDoneExecuting(
2697 token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698 } catch (RemoteException e) {
2699 // nothing to do.
2700 }
2701 } catch (Exception e) {
2702 if (!mInstrumentation.onException(s, e)) {
2703 throw new RuntimeException(
2704 "Unable to stop service " + s
2705 + ": " + e.toString(), e);
2706 }
2707 }
2708 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002709 //Slog.i(TAG, "Running services: " + mServices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002710 }
2711
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002712 public final ActivityClientRecord performResumeActivity(IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 boolean clearHide) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002714 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002715 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 + " finished=" + r.activity.mFinished);
2717 if (r != null && !r.activity.mFinished) {
2718 if (clearHide) {
2719 r.hideForNow = false;
2720 r.activity.mStartedActivity = false;
2721 }
2722 try {
Dianne Hackborn689586d2012-10-01 18:23:04 -07002723 r.activity.mFragments.noteStateNotSaved();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 if (r.pendingIntents != null) {
2725 deliverNewIntents(r, r.pendingIntents);
2726 r.pendingIntents = null;
2727 }
2728 if (r.pendingResults != null) {
2729 deliverResults(r, r.pendingResults);
2730 r.pendingResults = null;
2731 }
2732 r.activity.performResume();
2733
Bob Leee5408332009-09-04 18:31:17 -07002734 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07002735 UserHandle.myUserId(), r.activity.getComponentName().getClassName());
Bob Leee5408332009-09-04 18:31:17 -07002736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002737 r.paused = false;
2738 r.stopped = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 r.state = null;
2740 } catch (Exception e) {
2741 if (!mInstrumentation.onException(r.activity, e)) {
2742 throw new RuntimeException(
2743 "Unable to resume activity "
2744 + r.intent.getComponent().toShortString()
2745 + ": " + e.toString(), e);
2746 }
2747 }
2748 }
2749 return r;
2750 }
2751
Romain Guya998dff2012-03-23 18:58:36 -07002752 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002753 if (r.mPendingRemoveWindow != null) {
2754 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2755 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2756 if (wtoken != null) {
Jeff Brown98365d72012-08-19 20:30:52 -07002757 WindowManagerGlobal.getInstance().closeAll(wtoken,
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002758 r.activity.getClass().getName(), "Activity");
2759 }
2760 }
2761 r.mPendingRemoveWindow = null;
2762 r.mPendingRemoveWindowManager = null;
2763 }
2764
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002765 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
2766 boolean reallyResume) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002767 // If we are getting ready to gc after going to the background, well
2768 // we are back active so skip it.
2769 unscheduleGcIdler();
2770
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002771 ActivityClientRecord r = performResumeActivity(token, clearHide);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002772
2773 if (r != null) {
2774 final Activity a = r.activity;
2775
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002776 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002777 TAG, "Resume " + r + " started activity: " +
2778 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2779 + ", finished: " + a.mFinished);
2780
2781 final int forwardBit = isForward ?
2782 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
Bob Leee5408332009-09-04 18:31:17 -07002783
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002784 // If the window hasn't yet been added to the window manager,
2785 // and this guy didn't finish itself or start another activity,
2786 // then go ahead and add the window.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002787 boolean willBeVisible = !a.mStartedActivity;
2788 if (!willBeVisible) {
2789 try {
2790 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2791 a.getActivityToken());
2792 } catch (RemoteException e) {
2793 }
2794 }
2795 if (r.window == null && !a.mFinished && willBeVisible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002796 r.window = r.activity.getWindow();
2797 View decor = r.window.getDecorView();
2798 decor.setVisibility(View.INVISIBLE);
2799 ViewManager wm = a.getWindowManager();
2800 WindowManager.LayoutParams l = r.window.getAttributes();
2801 a.mDecor = decor;
2802 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2803 l.softInputMode |= forwardBit;
2804 if (a.mVisibleFromClient) {
2805 a.mWindowAdded = true;
2806 wm.addView(decor, l);
2807 }
2808
2809 // If the window has already been added, but during resume
2810 // we started another activity, then don't yet make the
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002811 // window visible.
2812 } else if (!willBeVisible) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002813 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 TAG, "Launch " + r + " mStartedActivity set");
2815 r.hideForNow = true;
2816 }
2817
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002818 // Get rid of anything left hanging around.
2819 cleanUpPendingRemoveWindows(r);
2820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002821 // The window is now visible if it has been added, we are not
2822 // simply finishing, and we are not starting another activity.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002823 if (!r.activity.mFinished && willBeVisible
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002824 && r.activity.mDecor != null && !r.hideForNow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002825 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002826 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002827 + r.activityInfo.name + " with newConfig " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002828 performConfigurationChanged(r.activity, r.newConfig);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07002829 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830 r.newConfig = null;
2831 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002832 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833 + isForward);
2834 WindowManager.LayoutParams l = r.window.getAttributes();
2835 if ((l.softInputMode
2836 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2837 != forwardBit) {
2838 l.softInputMode = (l.softInputMode
2839 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2840 | forwardBit;
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002841 if (r.activity.mVisibleFromClient) {
2842 ViewManager wm = a.getWindowManager();
2843 View decor = r.window.getDecorView();
2844 wm.updateViewLayout(decor, l);
2845 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002846 }
2847 r.activity.mVisibleFromServer = true;
2848 mNumVisibleActivities++;
2849 if (r.activity.mVisibleFromClient) {
2850 r.activity.makeVisible();
2851 }
2852 }
2853
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002854 if (!r.onlyLocalRequest) {
2855 r.nextIdle = mNewActivities;
2856 mNewActivities = r;
2857 if (localLOGV) Slog.v(
2858 TAG, "Scheduling idle handler for " + r);
2859 Looper.myQueue().addIdleHandler(new Idler());
2860 }
2861 r.onlyLocalRequest = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002863 // Tell the activity manager we have resumed.
2864 if (reallyResume) {
2865 try {
2866 ActivityManagerNative.getDefault().activityResumed(token);
2867 } catch (RemoteException ex) {
2868 }
2869 }
2870
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002871 } else {
2872 // If an exception was thrown when trying to resume, then
2873 // just end this activity.
2874 try {
2875 ActivityManagerNative.getDefault()
2876 .finishActivity(token, Activity.RESULT_CANCELED, null);
2877 } catch (RemoteException ex) {
2878 }
2879 }
2880 }
2881
2882 private int mThumbnailWidth = -1;
2883 private int mThumbnailHeight = -1;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002884 private Bitmap mAvailThumbnailBitmap = null;
2885 private Canvas mThumbnailCanvas = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002886
Romain Guy65b345f2011-07-27 18:51:50 -07002887 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002888 Bitmap thumbnail = mAvailThumbnailBitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002889 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002890 if (thumbnail == null) {
2891 int w = mThumbnailWidth;
2892 int h;
2893 if (w < 0) {
2894 Resources res = r.activity.getResources();
2895 mThumbnailHeight = h =
2896 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002897
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002898 mThumbnailWidth = w =
2899 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2900 } else {
2901 h = mThumbnailHeight;
2902 }
2903
2904 // On platforms where we don't want thumbnails, set dims to (0,0)
2905 if ((w > 0) && (h > 0)) {
Dianne Hackborndde331c2012-08-03 14:01:57 -07002906 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(),
2907 w, h, THUMBNAIL_FORMAT);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002908 thumbnail.eraseColor(0);
2909 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002910 }
2911
Dianne Hackbornfb3806d2010-12-09 13:14:12 -08002912 if (thumbnail != null) {
2913 Canvas cv = mThumbnailCanvas;
2914 if (cv == null) {
2915 mThumbnailCanvas = cv = new Canvas();
2916 }
2917
2918 cv.setBitmap(thumbnail);
2919 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2920 mAvailThumbnailBitmap = thumbnail;
2921 thumbnail = null;
2922 }
Dianne Hackborn6311d0a2011-08-02 16:37:58 -07002923 cv.setBitmap(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 }
Jim Miller0b2a6d02010-07-13 18:01:29 -07002925
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 } catch (Exception e) {
2927 if (!mInstrumentation.onException(r.activity, e)) {
2928 throw new RuntimeException(
2929 "Unable to create thumbnail of "
2930 + r.intent.getComponent().toShortString()
2931 + ": " + e.toString(), e);
2932 }
2933 thumbnail = null;
2934 }
2935
2936 return thumbnail;
2937 }
2938
Romain Guy65b345f2011-07-27 18:51:50 -07002939 private void handlePauseActivity(IBinder token, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002940 boolean userLeaving, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002941 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002942 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002943 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002944 if (userLeaving) {
2945 performUserLeavingActivity(r);
2946 }
Bob Leee5408332009-09-04 18:31:17 -07002947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002948 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002949 performPauseActivity(token, finished, r.isPreHoneycomb());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002950
Dianne Hackbornaa93bcd2010-10-27 13:57:00 -07002951 // Make sure any pending writes are now committed.
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002952 if (r.isPreHoneycomb()) {
2953 QueuedWork.waitToFinish();
2954 }
Dianne Hackbornad9b32112012-09-17 15:35:01 -07002955
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002956 // Tell the activity manager we have paused.
2957 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002958 ActivityManagerNative.getDefault().activityPaused(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002959 } catch (RemoteException ex) {
2960 }
2961 }
2962 }
2963
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002964 final void performUserLeavingActivity(ActivityClientRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 mInstrumentation.callActivityOnUserLeaving(r.activity);
2966 }
2967
2968 final Bundle performPauseActivity(IBinder token, boolean finished,
2969 boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002970 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002971 return r != null ? performPauseActivity(r, finished, saveState) : null;
2972 }
2973
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002974 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 boolean saveState) {
2976 if (r.paused) {
2977 if (r.activity.mFinished) {
2978 // If we are finishing, we won't call onResume() in certain cases.
2979 // So here we likewise don't want to call onPause() if the activity
2980 // isn't resumed.
2981 return null;
2982 }
2983 RuntimeException e = new RuntimeException(
2984 "Performing pause of activity that is not resumed: "
2985 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002986 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002987 }
2988 Bundle state = null;
2989 if (finished) {
2990 r.activity.mFinished = true;
2991 }
2992 try {
2993 // Next have the activity save its current state and managed dialogs...
2994 if (!r.activity.mFinished && saveState) {
2995 state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04002996 state.setAllowFds(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002997 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2998 r.state = state;
2999 }
3000 // Now we are idle.
3001 r.activity.mCalled = false;
3002 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003003 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
3004 r.activity.getComponentName().getClassName());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003005 if (!r.activity.mCalled) {
3006 throw new SuperNotCalledException(
3007 "Activity " + r.intent.getComponent().toShortString() +
3008 " did not call through to super.onPause()");
3009 }
3010
3011 } catch (SuperNotCalledException e) {
3012 throw e;
3013
3014 } catch (Exception e) {
3015 if (!mInstrumentation.onException(r.activity, e)) {
3016 throw new RuntimeException(
3017 "Unable to pause activity "
3018 + r.intent.getComponent().toShortString()
3019 + ": " + e.toString(), e);
3020 }
3021 }
3022 r.paused = true;
Jeff Hamilton52d32032011-01-08 15:31:26 -06003023
3024 // Notify any outstanding on paused listeners
3025 ArrayList<OnActivityPausedListener> listeners;
3026 synchronized (mOnPauseListeners) {
3027 listeners = mOnPauseListeners.remove(r.activity);
3028 }
3029 int size = (listeners != null ? listeners.size() : 0);
3030 for (int i = 0; i < size; i++) {
3031 listeners.get(i).onPaused(r.activity);
3032 }
3033
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003034 return state;
3035 }
3036
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003037 final void performStopActivity(IBinder token, boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003038 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003039 performStopActivityInner(r, null, false, saveState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003040 }
3041
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07003042 private static class StopInfo implements Runnable {
3043 ActivityClientRecord activity;
3044 Bundle state;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003045 Bitmap thumbnail;
3046 CharSequence description;
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07003047
3048 @Override public void run() {
3049 // Tell activity manager we have been stopped.
3050 try {
3051 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity);
3052 ActivityManagerNative.getDefault().activityStopped(
3053 activity.token, state, thumbnail, description);
3054 } catch (RemoteException ex) {
3055 }
3056 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003057 }
3058
Jeff Brownddaa9ac2011-11-11 20:16:14 -08003059 private static final class ProviderRefCount {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003060 public final IActivityManager.ContentProviderHolder holder;
3061 public final ProviderClientRecord client;
3062 public int stableCount;
3063 public int unstableCount;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08003064
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07003065 // When this is set, the stable and unstable ref counts are 0 and
3066 // we have a pending operation scheduled to remove the ref count
3067 // from the activity manager. On the activity manager we are still
3068 // holding an unstable ref, though it is not reflected in the counts
3069 // here.
3070 public boolean removePending;
3071
3072 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder,
3073 ProviderClientRecord inClient, int sCount, int uCount) {
3074 holder = inHolder;
3075 client = inClient;
3076 stableCount = sCount;
3077 unstableCount = uCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003078 }
3079 }
3080
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003081 /**
3082 * Core implementation of stopping an activity. Note this is a little
3083 * tricky because the server's meaning of stop is slightly different
3084 * than our client -- for the server, stop means to save state and give
3085 * it the result when it is done, but the window may still be visible.
3086 * For the client, we want to call onStop()/onStart() to indicate when
3087 * the activity's UI visibillity changes.
3088 */
Romain Guy65b345f2011-07-27 18:51:50 -07003089 private void performStopActivityInner(ActivityClientRecord r,
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003090 StopInfo info, boolean keepShown, boolean saveState) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003091 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003092 Bundle state = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003093 if (r != null) {
3094 if (!keepShown && r.stopped) {
3095 if (r.activity.mFinished) {
3096 // If we are finishing, we won't call onResume() in certain
3097 // cases. So here we likewise don't want to call onStop()
3098 // if the activity isn't resumed.
3099 return;
3100 }
3101 RuntimeException e = new RuntimeException(
3102 "Performing stop of activity that is not resumed: "
3103 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003104 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003105 }
3106
3107 if (info != null) {
3108 try {
3109 // First create a thumbnail for the activity...
Dianne Hackborn0500b3c2011-11-01 15:28:43 -07003110 // For now, don't create the thumbnail here; we are
3111 // doing that by doing a screen snapshot.
3112 info.thumbnail = null; //createThumbnailBitmap(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003113 info.description = r.activity.onCreateDescription();
3114 } catch (Exception e) {
3115 if (!mInstrumentation.onException(r.activity, e)) {
3116 throw new RuntimeException(
3117 "Unable to save state of activity "
3118 + r.intent.getComponent().toShortString()
3119 + ": " + e.toString(), e);
3120 }
3121 }
3122 }
3123
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003124 // Next have the activity save its current state and managed dialogs...
3125 if (!r.activity.mFinished && saveState) {
3126 if (r.state == null) {
3127 state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04003128 state.setAllowFds(false);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003129 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
3130 r.state = state;
3131 } else {
3132 state = r.state;
3133 }
3134 }
3135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003136 if (!keepShown) {
3137 try {
3138 // Now we are idle.
3139 r.activity.performStop();
3140 } catch (Exception e) {
3141 if (!mInstrumentation.onException(r.activity, e)) {
3142 throw new RuntimeException(
3143 "Unable to stop activity "
3144 + r.intent.getComponent().toShortString()
3145 + ": " + e.toString(), e);
3146 }
3147 }
3148 r.stopped = true;
3149 }
3150
3151 r.paused = true;
3152 }
3153 }
3154
Romain Guy65b345f2011-07-27 18:51:50 -07003155 private void updateVisibility(ActivityClientRecord r, boolean show) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 View v = r.activity.mDecor;
3157 if (v != null) {
3158 if (show) {
3159 if (!r.activity.mVisibleFromServer) {
3160 r.activity.mVisibleFromServer = true;
3161 mNumVisibleActivities++;
3162 if (r.activity.mVisibleFromClient) {
3163 r.activity.makeVisible();
3164 }
3165 }
3166 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003167 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003168 + r.activityInfo.name + " with new config " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003169 performConfigurationChanged(r.activity, r.newConfig);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003170 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003171 r.newConfig = null;
3172 }
3173 } else {
3174 if (r.activity.mVisibleFromServer) {
3175 r.activity.mVisibleFromServer = false;
3176 mNumVisibleActivities--;
3177 v.setVisibility(View.INVISIBLE);
3178 }
3179 }
3180 }
3181 }
3182
Romain Guy65b345f2011-07-27 18:51:50 -07003183 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003184 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003185 r.activity.mConfigChangeFlags |= configChanges;
3186
3187 StopInfo info = new StopInfo();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003188 performStopActivityInner(r, info, show, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003189
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003190 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003191 TAG, "Finishing stop of " + r + ": show=" + show
3192 + " win=" + r.window);
3193
3194 updateVisibility(r, show);
Bob Leee5408332009-09-04 18:31:17 -07003195
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08003196 // Make sure any pending writes are now committed.
3197 if (!r.isPreHoneycomb()) {
3198 QueuedWork.waitToFinish();
3199 }
3200
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07003201 // Schedule the call to tell the activity manager we have
3202 // stopped. We don't do this immediately, because we want to
3203 // have a chance for any other pending work (in particular memory
3204 // trim requests) to complete before you tell the activity
3205 // manager to proceed and allow us to go fully into the background.
3206 info.activity = r;
3207 info.state = r.state;
3208 mH.post(info);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003209 }
3210
3211 final void performRestartActivity(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003212 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003213 if (r.stopped) {
3214 r.activity.performRestart();
3215 r.stopped = false;
3216 }
3217 }
3218
Romain Guy65b345f2011-07-27 18:51:50 -07003219 private void handleWindowVisibility(IBinder token, boolean show) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003220 ActivityClientRecord r = mActivities.get(token);
Dianne Hackbornbfddc0f2010-12-14 11:28:01 -08003221
3222 if (r == null) {
3223 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
3224 return;
3225 }
3226
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003227 if (!show && !r.stopped) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003228 performStopActivityInner(r, null, show, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003229 } else if (show && r.stopped) {
3230 // If we are getting ready to gc after going to the background, well
3231 // we are back active so skip it.
3232 unscheduleGcIdler();
3233
3234 r.activity.performRestart();
3235 r.stopped = false;
3236 }
3237 if (r.activity.mDecor != null) {
Joe Onorato43a17652011-04-06 19:22:23 -07003238 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003239 TAG, "Handle window " + r + " visibility: " + show);
3240 updateVisibility(r, show);
3241 }
3242 }
3243
Romain Guy65b345f2011-07-27 18:51:50 -07003244 private void handleSleeping(IBinder token, boolean sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003245 ActivityClientRecord r = mActivities.get(token);
3246
3247 if (r == null) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08003248 Log.w(TAG, "handleSleeping: no activity for token " + token);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003249 return;
3250 }
3251
3252 if (sleeping) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08003253 if (!r.stopped && !r.isPreHoneycomb()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003254 try {
3255 // Now we are idle.
3256 r.activity.performStop();
3257 } catch (Exception e) {
3258 if (!mInstrumentation.onException(r.activity, e)) {
3259 throw new RuntimeException(
3260 "Unable to stop activity "
3261 + r.intent.getComponent().toShortString()
3262 + ": " + e.toString(), e);
3263 }
3264 }
3265 r.stopped = true;
3266 }
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08003267
3268 // Make sure any pending writes are now committed.
3269 if (!r.isPreHoneycomb()) {
3270 QueuedWork.waitToFinish();
3271 }
3272
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08003273 // Tell activity manager we slept.
3274 try {
3275 ActivityManagerNative.getDefault().activitySlept(r.token);
3276 } catch (RemoteException ex) {
3277 }
3278 } else {
3279 if (r.stopped && r.activity.mVisibleFromServer) {
3280 r.activity.performRestart();
3281 r.stopped = false;
3282 }
3283 }
3284 }
3285
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003286 private void handleSetCoreSettings(Bundle coreSettings) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08003287 synchronized (mPackages) {
3288 mCoreSettings = coreSettings;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08003289 }
3290 }
3291
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003292 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
3293 LoadedApk apk = peekPackageInfo(data.pkg, false);
3294 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003295 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003296 }
3297 apk = peekPackageInfo(data.pkg, true);
3298 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003299 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003300 }
3301 handleConfigurationChanged(mConfiguration, data.info);
Jeff Brown98365d72012-08-19 20:30:52 -07003302 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003303 }
3304
Romain Guy65b345f2011-07-27 18:51:50 -07003305 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003306 final int N = results.size();
3307 for (int i=0; i<N; i++) {
3308 ResultInfo ri = results.get(i);
3309 try {
3310 if (ri.mData != null) {
3311 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
3312 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003313 if (DEBUG_RESULTS) Slog.v(TAG,
Chris Tate8a7dc172009-03-24 20:11:42 -07003314 "Delivering result to activity " + r + " : " + ri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003315 r.activity.dispatchActivityResult(ri.mResultWho,
3316 ri.mRequestCode, ri.mResultCode, ri.mData);
3317 } catch (Exception e) {
3318 if (!mInstrumentation.onException(r.activity, e)) {
3319 throw new RuntimeException(
3320 "Failure delivering result " + ri + " to activity "
3321 + r.intent.getComponent().toShortString()
3322 + ": " + e.toString(), e);
3323 }
3324 }
3325 }
3326 }
3327
Romain Guy65b345f2011-07-27 18:51:50 -07003328 private void handleSendResult(ResultData res) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003329 ActivityClientRecord r = mActivities.get(res.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003330 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331 if (r != null) {
3332 final boolean resumed = !r.paused;
3333 if (!r.activity.mFinished && r.activity.mDecor != null
3334 && r.hideForNow && resumed) {
3335 // We had hidden the activity because it started another
3336 // one... we have gotten a result back and we are not
3337 // paused, so make sure our window is visible.
3338 updateVisibility(r, true);
3339 }
3340 if (resumed) {
3341 try {
3342 // Now we are idle.
3343 r.activity.mCalled = false;
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07003344 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003345 mInstrumentation.callActivityOnPause(r.activity);
3346 if (!r.activity.mCalled) {
3347 throw new SuperNotCalledException(
3348 "Activity " + r.intent.getComponent().toShortString()
3349 + " did not call through to super.onPause()");
3350 }
3351 } catch (SuperNotCalledException e) {
3352 throw e;
3353 } catch (Exception e) {
3354 if (!mInstrumentation.onException(r.activity, e)) {
3355 throw new RuntimeException(
3356 "Unable to pause activity "
3357 + r.intent.getComponent().toShortString()
3358 + ": " + e.toString(), e);
3359 }
3360 }
3361 }
3362 deliverResults(r, res.results);
3363 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07003364 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07003365 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 }
3367 }
3368 }
3369
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003370 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003371 return performDestroyActivity(token, finishing, 0, false);
3372 }
3373
Romain Guy65b345f2011-07-27 18:51:50 -07003374 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003375 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003376 ActivityClientRecord r = mActivities.get(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003377 Class activityClass = null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003378 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003379 if (r != null) {
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003380 activityClass = r.activity.getClass();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 r.activity.mConfigChangeFlags |= configChanges;
3382 if (finishing) {
3383 r.activity.mFinished = true;
3384 }
3385 if (!r.paused) {
3386 try {
3387 r.activity.mCalled = false;
3388 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07003389 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(),
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 r.activity.getComponentName().getClassName());
3391 if (!r.activity.mCalled) {
3392 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003393 "Activity " + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 + " did not call through to super.onPause()");
3395 }
3396 } catch (SuperNotCalledException e) {
3397 throw e;
3398 } catch (Exception e) {
3399 if (!mInstrumentation.onException(r.activity, e)) {
3400 throw new RuntimeException(
3401 "Unable to pause activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003402 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003403 + ": " + e.toString(), e);
3404 }
3405 }
3406 r.paused = true;
3407 }
3408 if (!r.stopped) {
3409 try {
3410 r.activity.performStop();
3411 } catch (SuperNotCalledException e) {
3412 throw e;
3413 } catch (Exception e) {
3414 if (!mInstrumentation.onException(r.activity, e)) {
3415 throw new RuntimeException(
3416 "Unable to stop activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003417 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003418 + ": " + e.toString(), e);
3419 }
3420 }
3421 r.stopped = true;
3422 }
3423 if (getNonConfigInstance) {
3424 try {
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07003425 r.lastNonConfigurationInstances
3426 = r.activity.retainNonConfigurationInstances();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003427 } catch (Exception e) {
3428 if (!mInstrumentation.onException(r.activity, e)) {
3429 throw new RuntimeException(
3430 "Unable to retain activity "
3431 + r.intent.getComponent().toShortString()
3432 + ": " + e.toString(), e);
3433 }
3434 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 }
3436 try {
3437 r.activity.mCalled = false;
Dianne Hackborn2dedce62010-04-15 14:45:25 -07003438 mInstrumentation.callActivityOnDestroy(r.activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003439 if (!r.activity.mCalled) {
3440 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003441 "Activity " + safeToComponentShortString(r.intent) +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003442 " did not call through to super.onDestroy()");
3443 }
3444 if (r.window != null) {
3445 r.window.closeAllPanels();
3446 }
3447 } catch (SuperNotCalledException e) {
3448 throw e;
3449 } catch (Exception e) {
3450 if (!mInstrumentation.onException(r.activity, e)) {
3451 throw new RuntimeException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003452 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3453 + ": " + e.toString(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454 }
3455 }
3456 }
3457 mActivities.remove(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003458 StrictMode.decrementExpectedActivityCount(activityClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003459 return r;
3460 }
3461
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003462 private static String safeToComponentShortString(Intent intent) {
3463 ComponentName component = intent.getComponent();
3464 return component == null ? "[Unknown]" : component.toShortString();
3465 }
3466
Romain Guy65b345f2011-07-27 18:51:50 -07003467 private void handleDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003468 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003469 ActivityClientRecord r = performDestroyActivity(token, finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003470 configChanges, getNonConfigInstance);
3471 if (r != null) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003472 cleanUpPendingRemoveWindows(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003473 WindowManager wm = r.activity.getWindowManager();
3474 View v = r.activity.mDecor;
3475 if (v != null) {
3476 if (r.activity.mVisibleFromServer) {
3477 mNumVisibleActivities--;
3478 }
3479 IBinder wtoken = v.getWindowToken();
3480 if (r.activity.mWindowAdded) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003481 if (r.onlyLocalRequest) {
3482 // Hold off on removing this until the new activity's
3483 // window is being added.
3484 r.mPendingRemoveWindow = v;
3485 r.mPendingRemoveWindowManager = wm;
3486 } else {
3487 wm.removeViewImmediate(v);
3488 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003489 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003490 if (wtoken != null && r.mPendingRemoveWindow == null) {
Jeff Brown98365d72012-08-19 20:30:52 -07003491 WindowManagerGlobal.getInstance().closeAll(wtoken,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003492 r.activity.getClass().getName(), "Activity");
3493 }
3494 r.activity.mDecor = null;
3495 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003496 if (r.mPendingRemoveWindow == null) {
3497 // If we are delaying the removal of the activity window, then
3498 // we can't clean up all windows here. Note that we can't do
3499 // so later either, which means any windows that aren't closed
3500 // by the app will leak. Well we try to warning them a lot
3501 // about leaking windows, because that is a bug, so if they are
3502 // using this recreate facility then they get to live with leaks.
Jeff Brown98365d72012-08-19 20:30:52 -07003503 WindowManagerGlobal.getInstance().closeAll(token,
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003504 r.activity.getClass().getName(), "Activity");
3505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003506
3507 // Mocked out contexts won't be participating in the normal
3508 // process lifecycle, but if we're running with a proper
3509 // ApplicationContext we need to have it tear down things
3510 // cleanly.
3511 Context c = r.activity.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08003512 if (c instanceof ContextImpl) {
3513 ((ContextImpl) c).scheduleFinalCleanup(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 r.activity.getClass().getName(), "Activity");
3515 }
3516 }
3517 if (finishing) {
3518 try {
3519 ActivityManagerNative.getDefault().activityDestroyed(token);
3520 } catch (RemoteException ex) {
3521 // If the system process has died, it's game over for everyone.
3522 }
3523 }
3524 }
3525
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003526 public final void requestRelaunchActivity(IBinder token,
3527 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3528 int configChanges, boolean notResumed, Configuration config,
3529 boolean fromServer) {
3530 ActivityClientRecord target = null;
3531
3532 synchronized (mPackages) {
3533 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3534 ActivityClientRecord r = mRelaunchingActivities.get(i);
3535 if (r.token == token) {
3536 target = r;
3537 if (pendingResults != null) {
3538 if (r.pendingResults != null) {
3539 r.pendingResults.addAll(pendingResults);
3540 } else {
3541 r.pendingResults = pendingResults;
3542 }
3543 }
3544 if (pendingNewIntents != null) {
3545 if (r.pendingIntents != null) {
3546 r.pendingIntents.addAll(pendingNewIntents);
3547 } else {
3548 r.pendingIntents = pendingNewIntents;
3549 }
3550 }
3551 break;
3552 }
3553 }
3554
3555 if (target == null) {
3556 target = new ActivityClientRecord();
3557 target.token = token;
3558 target.pendingResults = pendingResults;
3559 target.pendingIntents = pendingNewIntents;
3560 if (!fromServer) {
3561 ActivityClientRecord existing = mActivities.get(token);
3562 if (existing != null) {
3563 target.startsNotResumed = existing.paused;
3564 }
3565 target.onlyLocalRequest = true;
3566 }
3567 mRelaunchingActivities.add(target);
3568 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
3569 }
3570
3571 if (fromServer) {
3572 target.startsNotResumed = notResumed;
3573 target.onlyLocalRequest = false;
3574 }
3575 if (config != null) {
3576 target.createdConfig = config;
3577 }
3578 target.pendingConfigChanges |= configChanges;
3579 }
3580 }
3581
Romain Guy65b345f2011-07-27 18:51:50 -07003582 private void handleRelaunchActivity(ActivityClientRecord tmp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003583 // If we are getting ready to gc after going to the background, well
3584 // we are back active so skip it.
3585 unscheduleGcIdler();
3586
3587 Configuration changedConfig = null;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003588 int configChanges = 0;
Bob Leee5408332009-09-04 18:31:17 -07003589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003590 // First: make sure we have the most recent configuration and most
3591 // recent version of the activity, or skip it if some previous call
3592 // had taken a more recent version.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003593 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003594 int N = mRelaunchingActivities.size();
3595 IBinder token = tmp.token;
3596 tmp = null;
3597 for (int i=0; i<N; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003598 ActivityClientRecord r = mRelaunchingActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 if (r.token == token) {
3600 tmp = r;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003601 configChanges |= tmp.pendingConfigChanges;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 mRelaunchingActivities.remove(i);
3603 i--;
3604 N--;
3605 }
3606 }
Bob Leee5408332009-09-04 18:31:17 -07003607
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003608 if (tmp == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003609 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 return;
3611 }
Bob Leee5408332009-09-04 18:31:17 -07003612
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003613 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3614 + tmp.token + " with configChanges=0x"
3615 + Integer.toHexString(configChanges));
3616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003617 if (mPendingConfiguration != null) {
3618 changedConfig = mPendingConfiguration;
3619 mPendingConfiguration = null;
3620 }
3621 }
Bob Leee5408332009-09-04 18:31:17 -07003622
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003623 if (tmp.createdConfig != null) {
3624 // If the activity manager is passing us its current config,
3625 // assume that is really what we want regardless of what we
3626 // may have pending.
3627 if (mConfiguration == null
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003628 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3629 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3630 if (changedConfig == null
3631 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3632 changedConfig = tmp.createdConfig;
3633 }
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003634 }
3635 }
3636
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003637 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003638 + tmp.token + ": changedConfig=" + changedConfig);
3639
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003640 // If there was a pending configuration change, execute it first.
3641 if (changedConfig != null) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003642 mCurDefaultDisplayDpi = changedConfig.densityDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -07003643 updateDefaultDensity();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003644 handleConfigurationChanged(changedConfig, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003645 }
Bob Leee5408332009-09-04 18:31:17 -07003646
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003647 ActivityClientRecord r = mActivities.get(tmp.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003648 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003649 if (r == null) {
3650 return;
3651 }
Bob Leee5408332009-09-04 18:31:17 -07003652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003653 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003654 r.onlyLocalRequest = tmp.onlyLocalRequest;
Christopher Tateb70f3df2009-04-07 16:07:59 -07003655 Intent currentIntent = r.activity.mIntent;
Bob Leee5408332009-09-04 18:31:17 -07003656
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003657 r.activity.mChangingConfigurations = true;
3658
Dianne Hackborne2b04802010-12-09 09:24:55 -08003659 // Need to ensure state is saved.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003660 if (!r.paused) {
Dianne Hackborne2b04802010-12-09 09:24:55 -08003661 performPauseActivity(r.token, false, r.isPreHoneycomb());
3662 }
3663 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3664 r.state = new Bundle();
Dianne Hackborn9ecebbf2011-09-28 23:19:47 -04003665 r.state.setAllowFds(false);
Dianne Hackborne2b04802010-12-09 09:24:55 -08003666 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003667 }
Bob Leee5408332009-09-04 18:31:17 -07003668
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003669 handleDestroyActivity(r.token, false, configChanges, true);
Bob Leee5408332009-09-04 18:31:17 -07003670
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 r.activity = null;
3672 r.window = null;
3673 r.hideForNow = false;
3674 r.nextIdle = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07003675 // Merge any pending results and pending intents; don't just replace them
3676 if (tmp.pendingResults != null) {
3677 if (r.pendingResults == null) {
3678 r.pendingResults = tmp.pendingResults;
3679 } else {
3680 r.pendingResults.addAll(tmp.pendingResults);
3681 }
3682 }
3683 if (tmp.pendingIntents != null) {
3684 if (r.pendingIntents == null) {
3685 r.pendingIntents = tmp.pendingIntents;
3686 } else {
3687 r.pendingIntents.addAll(tmp.pendingIntents);
3688 }
3689 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003690 r.startsNotResumed = tmp.startsNotResumed;
Bob Leee5408332009-09-04 18:31:17 -07003691
Christopher Tateb70f3df2009-04-07 16:07:59 -07003692 handleLaunchActivity(r, currentIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003693 }
3694
Romain Guy65b345f2011-07-27 18:51:50 -07003695 private void handleRequestThumbnail(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003696 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003697 Bitmap thumbnail = createThumbnailBitmap(r);
3698 CharSequence description = null;
3699 try {
3700 description = r.activity.onCreateDescription();
3701 } catch (Exception e) {
3702 if (!mInstrumentation.onException(r.activity, e)) {
3703 throw new RuntimeException(
3704 "Unable to create description of activity "
3705 + r.intent.getComponent().toShortString()
3706 + ": " + e.toString(), e);
3707 }
3708 }
3709 //System.out.println("Reporting top thumbnail " + thumbnail);
3710 try {
3711 ActivityManagerNative.getDefault().reportThumbnail(
3712 token, thumbnail, description);
3713 } catch (RemoteException ex) {
3714 }
3715 }
3716
Dianne Hackborn73c14162012-09-19 15:45:06 -07003717 ArrayList<ComponentCallbacks2> collectComponentCallbacks(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003718 boolean allActivities, Configuration newConfig) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003719 ArrayList<ComponentCallbacks2> callbacks
3720 = new ArrayList<ComponentCallbacks2>();
Bob Leee5408332009-09-04 18:31:17 -07003721
Dianne Hackborn73c14162012-09-19 15:45:06 -07003722 synchronized (mPackages) {
3723 final int N = mAllApplications.size();
3724 for (int i=0; i<N; i++) {
3725 callbacks.add(mAllApplications.get(i));
3726 }
3727 if (mActivities.size() > 0) {
3728 for (ActivityClientRecord ar : mActivities.values()) {
3729 Activity a = ar.activity;
3730 if (a != null) {
3731 Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
3732 newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
3733 if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
3734 // If the activity is currently resumed, its configuration
3735 // needs to change right now.
3736 callbacks.add(a);
3737 } else if (thisConfig != null) {
3738 // Otherwise, we will tell it about the change
3739 // the next time it is resumed or shown. Note that
3740 // the activity manager may, before then, decide the
3741 // activity needs to be destroyed to handle its new
3742 // configuration.
3743 if (DEBUG_CONFIGURATION) {
3744 Slog.v(TAG, "Setting activity "
3745 + ar.activityInfo.name + " newConfig=" + thisConfig);
3746 }
3747 ar.newConfig = thisConfig;
Romain Guya998dff2012-03-23 18:58:36 -07003748 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003749 }
3750 }
3751 }
Dianne Hackborn73c14162012-09-19 15:45:06 -07003752 if (mServices.size() > 0) {
3753 for (Service service : mServices.values()) {
3754 callbacks.add(service);
3755 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003756 }
3757 }
3758 synchronized (mProviderMap) {
3759 if (mLocalProviders.size() > 0) {
Romain Guya998dff2012-03-23 18:58:36 -07003760 for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) {
3761 callbacks.add(providerClientRecord.mLocalProvider);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003762 }
3763 }
3764 }
Bob Leee5408332009-09-04 18:31:17 -07003765
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003766 return callbacks;
3767 }
Bob Leee5408332009-09-04 18:31:17 -07003768
Romain Guya998dff2012-03-23 18:58:36 -07003769 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003770 // Only for Activity objects, check that they actually call up to their
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003771 // superclass implementation. ComponentCallbacks2 is an interface, so
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 // we check the runtime type and act accordingly.
3773 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3774 if (activity != null) {
3775 activity.mCalled = false;
3776 }
Bob Leee5408332009-09-04 18:31:17 -07003777
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003778 boolean shouldChangeConfig = false;
3779 if ((activity == null) || (activity.mCurrentConfig == null)) {
3780 shouldChangeConfig = true;
3781 } else {
Bob Leee5408332009-09-04 18:31:17 -07003782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003783 // If the new config is the same as the config this Activity
3784 // is already running with then don't bother calling
3785 // onConfigurationChanged
3786 int diff = activity.mCurrentConfig.diff(config);
3787 if (diff != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003788 // If this activity doesn't handle any of the config changes
3789 // then don't bother calling onConfigurationChanged as we're
3790 // going to destroy it.
Dianne Hackborne6676352011-06-01 16:51:20 -07003791 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003792 shouldChangeConfig = true;
3793 }
3794 }
3795 }
Bob Leee5408332009-09-04 18:31:17 -07003796
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003797 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003798 + ": shouldChangeConfig=" + shouldChangeConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799 if (shouldChangeConfig) {
3800 cb.onConfigurationChanged(config);
Bob Leee5408332009-09-04 18:31:17 -07003801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 if (activity != null) {
3803 if (!activity.mCalled) {
3804 throw new SuperNotCalledException(
3805 "Activity " + activity.getLocalClassName() +
3806 " did not call through to super.onConfigurationChanged()");
3807 }
3808 activity.mConfigChangeFlags = 0;
3809 activity.mCurrentConfig = new Configuration(config);
3810 }
3811 }
3812 }
3813
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003814 public final void applyConfigurationToResources(Configuration config) {
3815 synchronized (mPackages) {
3816 applyConfigurationToResourcesLocked(config, null);
3817 }
3818 }
3819
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003820 final boolean applyConfigurationToResourcesLocked(Configuration config,
3821 CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003822 if (mResConfiguration == null) {
3823 mResConfiguration = new Configuration();
3824 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003825 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003826 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003827 + mResConfiguration.seq + ", newSeq=" + config.seq);
Dianne Hackbornae078162010-03-18 11:29:37 -07003828 return false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003829 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003830 int changes = mResConfiguration.updateFrom(config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003831 flushDisplayMetricsLocked();
3832 DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(
3833 Display.DEFAULT_DISPLAY, null);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003834
3835 if (compat != null && (mResCompatibilityInfo == null ||
3836 !mResCompatibilityInfo.equals(compat))) {
3837 mResCompatibilityInfo = compat;
3838 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
3839 | ActivityInfo.CONFIG_SCREEN_SIZE
3840 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
3841 }
Bob Leee5408332009-09-04 18:31:17 -07003842
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003843 // set it for java, this also affects newly created Resources
3844 if (config.locale != null) {
3845 Locale.setDefault(config.locale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003846 }
Bob Leee5408332009-09-04 18:31:17 -07003847
Jeff Browna492c3a2012-08-23 19:48:44 -07003848 Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
Bob Leee5408332009-09-04 18:31:17 -07003849
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08003850 ApplicationPackageManager.configurationChanged();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003851 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
Dianne Hackborn756220b2012-08-14 16:45:30 -07003852
3853 Configuration tmpConfig = null;
3854
3855 Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it =
3856 mActiveResources.entrySet().iterator();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003857 while (it.hasNext()) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07003858 Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
3859 Resources r = entry.getValue().get();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003860 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003861 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003862 + r + " config to: " + config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003863 int displayId = entry.getKey().mDisplayId;
3864 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
3865 DisplayMetrics dm = defaultDisplayMetrics;
3866 Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
3867 if (!isDefaultDisplay || overrideConfig != null) {
Dianne Hackborn756220b2012-08-14 16:45:30 -07003868 if (tmpConfig == null) {
3869 tmpConfig = new Configuration();
3870 }
3871 tmpConfig.setTo(config);
Jeff Browna492c3a2012-08-23 19:48:44 -07003872 if (!isDefaultDisplay) {
3873 dm = getDisplayMetricsLocked(displayId, null);
3874 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
3875 }
3876 if (overrideConfig != null) {
3877 tmpConfig.updateFrom(overrideConfig);
3878 }
Dianne Hackborn756220b2012-08-14 16:45:30 -07003879 r.updateConfiguration(tmpConfig, dm, compat);
3880 } else {
3881 r.updateConfiguration(config, dm, compat);
3882 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003883 //Slog.i(TAG, "Updated app resources " + v.getKey()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003884 // + " " + r + ": " + r.getConfiguration());
3885 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003886 //Slog.i(TAG, "Removing old resources " + v.getKey());
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003887 it.remove();
3888 }
3889 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003890
3891 return changes != 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003892 }
Dianne Hackborn836e2622011-10-04 18:32:39 -07003893
Jeff Browna492c3a2012-08-23 19:48:44 -07003894 final void applyNonDefaultDisplayMetricsToConfigurationLocked(
3895 DisplayMetrics dm, Configuration config) {
Jeff Browna492c3a2012-08-23 19:48:44 -07003896 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH;
Jeff Browna492c3a2012-08-23 19:48:44 -07003897 config.densityDpi = dm.densityDpi;
3898 config.screenWidthDp = (int)(dm.widthPixels / dm.density);
3899 config.screenHeightDp = (int)(dm.heightPixels / dm.density);
Dianne Hackbornfe37f8f2012-09-30 12:24:33 -07003900 int sl = Configuration.resetScreenLayout(config.screenLayout);
3901 if (dm.widthPixels > dm.heightPixels) {
3902 config.orientation = Configuration.ORIENTATION_LANDSCAPE;
3903 config.screenLayout = Configuration.reduceScreenLayout(sl,
3904 config.screenWidthDp, config.screenHeightDp);
3905 } else {
3906 config.orientation = Configuration.ORIENTATION_PORTRAIT;
3907 config.screenLayout = Configuration.reduceScreenLayout(sl,
3908 config.screenHeightDp, config.screenWidthDp);
3909 }
Jeff Browna492c3a2012-08-23 19:48:44 -07003910 config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate
3911 config.compatScreenWidthDp = config.screenWidthDp;
3912 config.compatScreenHeightDp = config.screenHeightDp;
3913 config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp;
3914 }
3915
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003916 final Configuration applyCompatConfiguration(int displayDensity) {
Dianne Hackborn836e2622011-10-04 18:32:39 -07003917 Configuration config = mConfiguration;
3918 if (mCompatConfiguration == null) {
3919 mCompatConfiguration = new Configuration();
3920 }
3921 mCompatConfiguration.setTo(mConfiguration);
3922 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003923 mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration);
Dianne Hackborn836e2622011-10-04 18:32:39 -07003924 config = mCompatConfiguration;
3925 }
3926 return config;
3927 }
3928
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003929 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003930
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003931 int configDiff = 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003932
3933 synchronized (mPackages) {
3934 if (mPendingConfiguration != null) {
3935 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3936 config = mPendingConfiguration;
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003937 mCurDefaultDisplayDpi = config.densityDpi;
Dianne Hackborndde331c2012-08-03 14:01:57 -07003938 updateDefaultDensity();
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003939 }
3940 mPendingConfiguration = null;
3941 }
3942
3943 if (config == null) {
3944 return;
3945 }
3946
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003947 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003948 + config);
3949
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003950 applyConfigurationToResourcesLocked(config, compat);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003951
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003952 if (mConfiguration == null) {
3953 mConfiguration = new Configuration();
3954 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003955 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003956 return;
3957 }
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003958 configDiff = mConfiguration.diff(config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003959 mConfiguration.updateFrom(config);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07003960 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003961 }
Dianne Hackborn73c14162012-09-19 15:45:06 -07003962
3963 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
3964
Romain Guy65b345f2011-07-27 18:51:50 -07003965 // Cleanup hardware accelerated stuff
Jeff Brown98365d72012-08-19 20:30:52 -07003966 WindowManagerGlobal.getInstance().trimLocalMemory();
Bob Leee5408332009-09-04 18:31:17 -07003967
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003968 freeTextLayoutCachesIfNeeded(configDiff);
3969
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003970 if (callbacks != null) {
3971 final int N = callbacks.size();
3972 for (int i=0; i<N; i++) {
3973 performConfigurationChanged(callbacks.get(i), config);
3974 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003975 }
3976 }
3977
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003978 final void freeTextLayoutCachesIfNeeded(int configDiff) {
3979 if (configDiff != 0) {
3980 // Ask text layout engine to free its caches if there is a locale change
3981 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0);
3982 if (hasLocaleConfigChange) {
3983 Canvas.freeTextLayoutCaches();
3984 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches");
3985 }
3986 }
3987 }
3988
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003989 final void handleActivityConfigurationChanged(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003990 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003991 if (r == null || r.activity == null) {
3992 return;
3993 }
Bob Leee5408332009-09-04 18:31:17 -07003994
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003995 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003996 + r.activityInfo.name);
3997
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003998 performConfigurationChanged(r.activity, mCompatConfiguration);
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07003999
4000 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004001 }
4002
Romain Guy7eabe552011-07-21 14:56:34 -07004003 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08004004 if (start) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08004005 try {
Romain Guy7eabe552011-07-21 14:56:34 -07004006 switch (profileType) {
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004007 default:
4008 mProfiler.setProfiler(pcd.path, pcd.fd);
4009 mProfiler.autoStopProfiler = false;
4010 mProfiler.startProfiling();
Romain Guy7eabe552011-07-21 14:56:34 -07004011 break;
4012 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08004013 } catch (RuntimeException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004014 Slog.w(TAG, "Profiling failed on path " + pcd.path
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08004015 + " -- can the process access this path?");
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07004016 } finally {
4017 try {
4018 pcd.fd.close();
4019 } catch (IOException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004020 Slog.w(TAG, "Failure closing profile fd", e);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07004021 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08004022 }
4023 } else {
Romain Guy7eabe552011-07-21 14:56:34 -07004024 switch (profileType) {
Romain Guy7eabe552011-07-21 14:56:34 -07004025 default:
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004026 mProfiler.stopProfiling();
Romain Guy7eabe552011-07-21 14:56:34 -07004027 break;
Romain Guy7eabe552011-07-21 14:56:34 -07004028 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08004029 }
4030 }
Bob Leee5408332009-09-04 18:31:17 -07004031
Romain Guya998dff2012-03-23 18:58:36 -07004032 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
Andy McFadden824c5102010-07-09 16:26:57 -07004033 if (managed) {
4034 try {
4035 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
4036 } catch (IOException e) {
4037 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
4038 + " -- can the process access this path?");
4039 } finally {
4040 try {
4041 dhd.fd.close();
4042 } catch (IOException e) {
4043 Slog.w(TAG, "Failure closing profile fd", e);
4044 }
4045 }
4046 } else {
Andy McFadden06a6b552010-07-13 16:28:09 -07004047 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
Andy McFadden824c5102010-07-09 16:26:57 -07004048 }
4049 }
4050
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07004051 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
4052 boolean hasPkgInfo = false;
4053 if (packages != null) {
4054 for (int i=packages.length-1; i>=0; i--) {
4055 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
4056 if (!hasPkgInfo) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004057 WeakReference<LoadedApk> ref;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07004058 ref = mPackages.get(packages[i]);
4059 if (ref != null && ref.get() != null) {
4060 hasPkgInfo = true;
4061 } else {
4062 ref = mResourcePackages.get(packages[i]);
4063 if (ref != null && ref.get() != null) {
4064 hasPkgInfo = true;
4065 }
4066 }
4067 }
4068 mPackages.remove(packages[i]);
4069 mResourcePackages.remove(packages[i]);
4070 }
4071 }
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08004072 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07004073 hasPkgInfo);
4074 }
4075
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004076 final void handleLowMemory() {
Dianne Hackborn73c14162012-09-19 15:45:06 -07004077 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
Bob Leee5408332009-09-04 18:31:17 -07004078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004079 final int N = callbacks.size();
4080 for (int i=0; i<N; i++) {
4081 callbacks.get(i).onLowMemory();
4082 }
4083
Chris Tatece229052009-03-25 16:44:52 -07004084 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
4085 if (Process.myUid() != Process.SYSTEM_UID) {
4086 int sqliteReleased = SQLiteDatabase.releaseMemory();
4087 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
4088 }
Bob Leee5408332009-09-04 18:31:17 -07004089
Mike Reedcaf0df12009-04-27 14:32:05 -04004090 // Ask graphics to free up as much as possible (font/image caches)
4091 Canvas.freeCaches();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004092
Fabrice Di Meglio30ca5cd2012-05-07 17:45:44 -07004093 // Ask text layout engine to free also as much as possible
4094 Canvas.freeTextLayoutCaches();
4095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004096 BinderInternal.forceGc("mem");
4097 }
4098
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004099 final void handleTrimMemory(int level) {
Dianne Hackborn162bc0e2012-04-09 14:06:16 -07004100 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004101
Jeff Brown98365d72012-08-19 20:30:52 -07004102 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
Romain Guy19f86e82012-04-23 15:19:07 -07004103 windowManager.startTrimMemory(level);
4104
Dianne Hackborn73c14162012-09-19 15:45:06 -07004105 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004106
4107 final int N = callbacks.size();
Romain Guya998dff2012-03-23 18:58:36 -07004108 for (int i = 0; i < N; i++) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004109 callbacks.get(i).onTrimMemory(level);
4110 }
Romain Guy19f86e82012-04-23 15:19:07 -07004111
Jeff Brown98365d72012-08-19 20:30:52 -07004112 windowManager.endTrimMemory();
Dianne Hackbornce86ba82011-07-13 19:33:41 -07004113 }
4114
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004115 private void setupGraphicsSupport(LoadedApk info, File cacheDir) {
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004116 if (Process.isIsolated()) {
4117 // Isolated processes aren't going to do UI.
4118 return;
4119 }
Romain Guya9582652011-11-10 14:20:10 -08004120 try {
4121 int uid = Process.myUid();
4122 String[] packages = getPackageManager().getPackagesForUid(uid);
4123
4124 // If there are several packages in this application we won't
4125 // initialize the graphics disk caches
Dianne Hackborna0c283e2012-02-09 10:47:01 -08004126 if (packages != null && packages.length == 1) {
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004127 HardwareRenderer.setupDiskCache(cacheDir);
4128 RenderScript.setupDiskCache(cacheDir);
Romain Guya9582652011-11-10 14:20:10 -08004129 }
4130 } catch (RemoteException e) {
4131 // Ignore
4132 }
Dianne Hackborndde331c2012-08-03 14:01:57 -07004133 }
4134
4135 private void updateDefaultDensity() {
4136 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED
4137 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE
4138 && !mDensityCompatMode) {
4139 Slog.i(TAG, "Switching default density from "
4140 + DisplayMetrics.DENSITY_DEVICE + " to "
4141 + mCurDefaultDisplayDpi);
4142 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi;
4143 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4144 }
4145 }
4146
Romain Guy65b345f2011-07-27 18:51:50 -07004147 private void handleBindApplication(AppBindData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004148 mBoundApplication = data;
4149 mConfiguration = new Configuration(data.config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07004150 mCompatConfiguration = new Configuration(data.config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004151
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004152 mProfiler = new Profiler();
4153 mProfiler.profileFile = data.initProfileFile;
4154 mProfiler.profileFd = data.initProfileFd;
4155 mProfiler.autoStopProfiler = data.initAutoStopProfiler;
4156
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004157 // send up app name; do this *before* waiting for debugger
Christopher Tate8ee038d2009-11-06 11:30:20 -08004158 Process.setArgV0(data.processName);
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004159 android.ddm.DdmHandleAppName.setAppName(data.processName,
4160 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004161
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004162 if (data.persistent) {
4163 // Persistent processes on low-memory devices do not get to
4164 // use hardware accelerated drawing, since this can add too much
4165 // overhead to the process.
Jeff Brown98365d72012-08-19 20:30:52 -07004166 if (!ActivityManager.isHighEndGfx()) {
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004167 HardwareRenderer.disable(false);
4168 }
4169 }
Romain Guya9582652011-11-10 14:20:10 -08004170
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004171 if (mProfiler.profileFd != null) {
4172 mProfiler.startProfiling();
Dianne Hackborn62f20ec2011-08-15 17:40:28 -07004173 }
4174
Joe Onoratod630f102011-03-17 18:42:26 -07004175 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
4176 // implementation to use the pool executor. Normally, we use the
4177 // serialized executor as the default. This has to happen in the
4178 // main thread so the main looper is set right.
Dianne Hackborn81e92762011-10-09 16:00:21 -07004179 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) {
Joe Onoratod630f102011-03-17 18:42:26 -07004180 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
4181 }
4182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004183 /*
4184 * Before spawning a new process, reset the time zone to be the system time zone.
4185 * This needs to be done because the system time zone could have changed after the
4186 * the spawning of this process. Without doing this this process would have the incorrect
4187 * system time zone.
4188 */
4189 TimeZone.setDefault(null);
4190
4191 /*
4192 * Initialize the default locale in this process for the reasons we set the time zone.
4193 */
4194 Locale.setDefault(data.config.locale);
4195
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07004196 /*
4197 * Update the system configuration since its preloaded and might not
4198 * reflect configuration changes. The configuration object passed
4199 * in AppBindData can be safely assumed to be up to date
4200 */
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07004201 applyConfigurationToResourcesLocked(data.config, data.compatInfo);
Dianne Hackborn908aecc2012-07-31 16:37:34 -07004202 mCurDefaultDisplayDpi = data.config.densityDpi;
4203 applyCompatConfiguration(mCurDefaultDisplayDpi);
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07004204
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004205 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004206
Dianne Hackborndde331c2012-08-03 14:01:57 -07004207 /**
4208 * Switch this process to density compatibility mode if needed.
4209 */
4210 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
4211 == 0) {
4212 mDensityCompatMode = true;
4213 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
4214 }
4215 updateDefaultDensity();
4216
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004217 final ContextImpl appContext = new ContextImpl();
4218 appContext.init(data.info, null, this);
Amith Yamasani11de39a2012-08-17 18:00:52 -07004219 if (!Process.isIsolated()) {
4220 final File cacheDir = appContext.getCacheDir();
Jeff Sharkeye1d330a2012-05-02 13:46:21 -07004221
Amith Yamasani92d57052012-08-23 10:07:52 -07004222 if (cacheDir != null) {
4223 // Provide a usable directory for temporary files
4224 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath());
4225
4226 setupGraphicsSupport(data.info, cacheDir);
4227 } else {
4228 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory");
4229 }
Amith Yamasani11de39a2012-08-17 18:00:52 -07004230 }
Dianne Hackborn96e240f2009-07-26 17:42:30 -07004231 /**
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07004232 * For system applications on userdebug/eng builds, log stack
4233 * traces of disk and network access to dropbox for analysis.
4234 */
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07004235 if ((data.appInfo.flags &
4236 (ApplicationInfo.FLAG_SYSTEM |
Brad Fitzpatrick50d66f92010-09-13 21:29:05 -07004237 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
4238 StrictMode.conditionallyEnableDebugLogging();
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07004239 }
4240
4241 /**
Brad Fitzpatrickb6e18412010-10-28 14:50:05 -07004242 * For apps targetting SDK Honeycomb or later, we don't allow
4243 * network usage on the main event loop / UI thread.
4244 *
4245 * Note to those grepping: this is what ultimately throws
4246 * NetworkOnMainThreadException ...
4247 */
4248 if (data.appInfo.targetSdkVersion > 9) {
4249 StrictMode.enableDeathOnNetwork();
4250 }
4251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004252 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
4253 // XXX should have option to change the port.
4254 Debug.changeDebugPort(8100);
4255 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004256 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004257 + " is waiting for the debugger on port 8100...");
4258
4259 IActivityManager mgr = ActivityManagerNative.getDefault();
4260 try {
4261 mgr.showWaitingForDebugger(mAppThread, true);
4262 } catch (RemoteException ex) {
4263 }
4264
4265 Debug.waitForDebugger();
4266
4267 try {
4268 mgr.showWaitingForDebugger(mAppThread, false);
4269 } catch (RemoteException ex) {
4270 }
4271
4272 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004273 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004274 + " can be debugged on port 8100...");
4275 }
4276 }
4277
Siva Velusamy92a8b222012-03-09 16:24:04 -08004278 // Enable OpenGL tracing if required
4279 if (data.enableOpenGlTrace) {
4280 GLUtils.enableTracing();
4281 }
4282
Robert Greenwalt434203a2010-10-11 16:00:27 -07004283 /**
4284 * Initialize the default http proxy in this process for the reasons we set the time zone.
4285 */
4286 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
Dianne Hackbornd4d32c52011-11-08 17:33:59 -08004287 if (b != null) {
4288 // In pre-boot mode (doing initial launch to collect password), not
4289 // all system is up. This includes the connectivity service, so don't
4290 // crash if we can't get it.
4291 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
4292 try {
4293 ProxyProperties proxyProperties = service.getProxy();
4294 Proxy.setHttpProxySystemProperty(proxyProperties);
4295 } catch (RemoteException e) {}
4296 }
Robert Greenwalt434203a2010-10-11 16:00:27 -07004297
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004298 if (data.instrumentationName != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004299 InstrumentationInfo ii = null;
4300 try {
4301 ii = appContext.getPackageManager().
4302 getInstrumentationInfo(data.instrumentationName, 0);
4303 } catch (PackageManager.NameNotFoundException e) {
4304 }
4305 if (ii == null) {
4306 throw new RuntimeException(
4307 "Unable to find instrumentation info for: "
4308 + data.instrumentationName);
4309 }
4310
4311 mInstrumentationAppDir = ii.sourceDir;
Brian Carlstromd893a892012-04-01 21:30:26 -07004312 mInstrumentationAppLibraryDir = ii.nativeLibraryDir;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004313 mInstrumentationAppPackage = ii.packageName;
4314 mInstrumentedAppDir = data.info.getAppDir();
Brian Carlstromd893a892012-04-01 21:30:26 -07004315 mInstrumentedAppLibraryDir = data.info.getLibDir();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004316
4317 ApplicationInfo instrApp = new ApplicationInfo();
4318 instrApp.packageName = ii.packageName;
4319 instrApp.sourceDir = ii.sourceDir;
4320 instrApp.publicSourceDir = ii.publicSourceDir;
4321 instrApp.dataDir = ii.dataDir;
Kenny Root85387d72010-08-26 10:13:11 -07004322 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004323 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004324 appContext.getClassLoader(), false, true);
Dianne Hackborn21556372010-02-04 16:34:40 -08004325 ContextImpl instrContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004326 instrContext.init(pi, null, this);
4327
4328 try {
4329 java.lang.ClassLoader cl = instrContext.getClassLoader();
4330 mInstrumentation = (Instrumentation)
4331 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
4332 } catch (Exception e) {
4333 throw new RuntimeException(
4334 "Unable to instantiate instrumentation "
4335 + data.instrumentationName + ": " + e.toString(), e);
4336 }
4337
4338 mInstrumentation.init(this, instrContext, appContext,
4339 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
4340
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004341 if (mProfiler.profileFile != null && !ii.handleProfiling
4342 && mProfiler.profileFd == null) {
4343 mProfiler.handlingProfiling = true;
4344 File file = new File(mProfiler.profileFile);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004345 file.getParentFile().mkdirs();
4346 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
4347 }
4348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004349 } else {
4350 mInstrumentation = new Instrumentation();
4351 }
4352
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08004353 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
Dianne Hackbornde398512011-01-18 18:45:21 -08004354 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08004355 }
4356
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004357 // Allow disk access during application and provider setup. This could
Jeff Sharkey7c501672012-02-28 12:08:37 -08004358 // block processing ordered broadcasts, but later processing would
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004359 // probably end up doing the same disk access.
Jeff Sharkey7c501672012-02-28 12:08:37 -08004360 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004361 try {
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004362 // If the app is being launched for full backup or restore, bring it up in
4363 // a restricted environment with the base application class.
4364 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4365 mInitialApplication = app;
Jeff Sharkey7c501672012-02-28 12:08:37 -08004366
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004367 // don't bring up providers in restricted mode; they may depend on the
4368 // app's custom Application class
4369 if (!data.restrictedBackupMode) {
4370 List<ProviderInfo> providers = data.providers;
4371 if (providers != null) {
4372 installContentProviders(app, providers);
4373 // For process that contains content providers, we want to
4374 // ensure that the JIT is enabled "at some point".
4375 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4376 }
4377 }
4378
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004379 // Do this after providers, since instrumentation tests generally start their
4380 // test thread at this point, and we don't want that racing.
4381 try {
4382 mInstrumentation.onCreate(data.instrumentationArgs);
4383 }
4384 catch (Exception e) {
4385 throw new RuntimeException(
4386 "Exception thrown in onCreate() of "
4387 + data.instrumentationName + ": " + e.toString(), e);
4388 }
4389
Jeff Sharkey6bff62c2012-02-29 12:26:36 -08004390 try {
4391 mInstrumentation.callApplicationOnCreate(app);
4392 } catch (Exception e) {
4393 if (!mInstrumentation.onException(app, e)) {
4394 throw new RuntimeException(
4395 "Unable to create application " + app.getClass().getName()
4396 + ": " + e.toString(), e);
4397 }
4398 }
4399 } finally {
4400 StrictMode.setThreadPolicy(savedPolicy);
4401 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004402 }
4403
4404 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
4405 IActivityManager am = ActivityManagerNative.getDefault();
Jeff Sharkey3ad9d002011-09-15 15:51:54 -07004406 if (mProfiler.profileFile != null && mProfiler.handlingProfiling
4407 && mProfiler.profileFd == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004408 Debug.stopMethodTracing();
4409 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004410 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004411 // + ", app thr: " + mAppThread);
4412 try {
4413 am.finishInstrumentation(mAppThread, resultCode, results);
4414 } catch (RemoteException ex) {
4415 }
4416 }
4417
Romain Guy65b345f2011-07-27 18:51:50 -07004418 private void installContentProviders(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 Context context, List<ProviderInfo> providers) {
4420 final ArrayList<IActivityManager.ContentProviderHolder> results =
4421 new ArrayList<IActivityManager.ContentProviderHolder>();
4422
Romain Guya998dff2012-03-23 18:58:36 -07004423 for (ProviderInfo cpi : providers) {
Dianne Hackborn40e9f292012-11-27 19:12:23 -08004424 if (DEBUG_PROVIDER) {
4425 StringBuilder buf = new StringBuilder(128);
4426 buf.append("Pub ");
4427 buf.append(cpi.authority);
4428 buf.append(": ");
4429 buf.append(cpi.name);
4430 Log.i(TAG, buf.toString());
4431 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004432 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4433 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4434 if (cph != null) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004435 cph.noReleaseNeeded = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004436 results.add(cph);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004437 }
4438 }
4439
4440 try {
4441 ActivityManagerNative.getDefault().publishContentProviders(
4442 getApplicationThread(), results);
4443 } catch (RemoteException ex) {
4444 }
4445 }
4446
Jeff Sharkey6d515712012-09-20 16:06:08 -07004447 public final IContentProvider acquireProvider(
4448 Context c, String auth, int userId, boolean stable) {
4449 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004450 if (provider != null) {
4451 return provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452 }
4453
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004454 // There is a possible race here. Another thread may try to acquire
4455 // the same provider at the same time. When this happens, we want to ensure
4456 // that the first one wins.
4457 // Note that we cannot hold the lock while acquiring and installing the
4458 // provider since it might take a long time to run and it could also potentially
4459 // be re-entrant in the case where the provider is in the same process.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004460 IActivityManager.ContentProviderHolder holder = null;
4461 try {
4462 holder = ActivityManagerNative.getDefault().getContentProvider(
Jeff Sharkey6d515712012-09-20 16:06:08 -07004463 getApplicationThread(), auth, userId, stable);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004464 } catch (RemoteException ex) {
4465 }
4466 if (holder == null) {
Jeff Sharkey6d515712012-09-20 16:06:08 -07004467 Slog.e(TAG, "Failed to find provider info for " + auth);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004468 return null;
4469 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004470
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004471 // Install provider will increment the reference count for us, and break
4472 // any ties in the race.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004473 holder = installProvider(c, holder, holder.info,
4474 true /*noisy*/, holder.noReleaseNeeded, stable);
4475 return holder.provider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004476 }
4477
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004478 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) {
4479 if (stable) {
4480 prc.stableCount += 1;
4481 if (prc.stableCount == 1) {
4482 // We are acquiring a new stable reference on the provider.
4483 int unstableDelta;
4484 if (prc.removePending) {
4485 // We have a pending remove operation, which is holding the
4486 // last unstable reference. At this point we are converting
4487 // that unstable reference to our new stable reference.
4488 unstableDelta = -1;
4489 // Cancel the removal of the provider.
4490 if (DEBUG_PROVIDER) {
4491 Slog.v(TAG, "incProviderRef: stable "
4492 + "snatched provider from the jaws of death");
4493 }
4494 prc.removePending = false;
4495 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4496 } else {
4497 unstableDelta = 0;
4498 }
4499 try {
4500 if (DEBUG_PROVIDER) {
4501 Slog.v(TAG, "incProviderRef Now stable - "
4502 + prc.holder.info.name + ": unstableDelta="
4503 + unstableDelta);
4504 }
4505 ActivityManagerNative.getDefault().refContentProvider(
4506 prc.holder.connection, 1, unstableDelta);
4507 } catch (RemoteException e) {
4508 //do nothing content provider object is dead any way
4509 }
4510 }
4511 } else {
4512 prc.unstableCount += 1;
4513 if (prc.unstableCount == 1) {
4514 // We are acquiring a new unstable reference on the provider.
4515 if (prc.removePending) {
4516 // Oh look, we actually have a remove pending for the
4517 // provider, which is still holding the last unstable
4518 // reference. We just need to cancel that to take new
4519 // ownership of the reference.
4520 if (DEBUG_PROVIDER) {
4521 Slog.v(TAG, "incProviderRef: unstable "
4522 + "snatched provider from the jaws of death");
4523 }
4524 prc.removePending = false;
4525 mH.removeMessages(H.REMOVE_PROVIDER, prc);
4526 } else {
4527 // First unstable ref, increment our count in the
4528 // activity manager.
4529 try {
4530 if (DEBUG_PROVIDER) {
4531 Slog.v(TAG, "incProviderRef: Now unstable - "
4532 + prc.holder.info.name);
4533 }
4534 ActivityManagerNative.getDefault().refContentProvider(
4535 prc.holder.connection, 0, 1);
4536 } catch (RemoteException e) {
4537 //do nothing content provider object is dead any way
4538 }
4539 }
4540 }
4541 }
4542 }
4543
Jeff Sharkey6d515712012-09-20 16:06:08 -07004544 public final IContentProvider acquireExistingProvider(
4545 Context c, String auth, int userId, boolean stable) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004546 synchronized (mProviderMap) {
Jeff Sharkey6d515712012-09-20 16:06:08 -07004547 final ProviderKey key = new ProviderKey(auth, userId);
4548 final ProviderClientRecord pr = mProviderMap.get(key);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004549 if (pr == null) {
4550 return null;
4551 }
4552
4553 IContentProvider provider = pr.mProvider;
4554 IBinder jBinder = provider.asBinder();
Dianne Hackbornc428aae2012-10-03 16:38:22 -07004555 if (!jBinder.isBinderAlive()) {
4556 // The hosting process of the provider has died; we can't
4557 // use this one.
4558 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId
4559 + ": existing object's process dead");
4560 handleUnstableProviderDiedLocked(jBinder, true);
4561 return null;
4562 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004563
4564 // Only increment the ref count if we have one. If we don't then the
4565 // provider is not reference counted and never needs to be released.
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07004566 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004567 if (prc != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004568 incProviderRefLocked(prc, stable);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004569 }
4570 return provider;
4571 }
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07004572 }
4573
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004574 public final boolean releaseProvider(IContentProvider provider, boolean stable) {
4575 if (provider == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004576 return false;
4577 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004579 IBinder jBinder = provider.asBinder();
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004580 synchronized (mProviderMap) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004581 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004582 if (prc == null) {
4583 // The provider has no ref count, no release is needed.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004584 return false;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004585 }
4586
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004587 boolean lastRef = false;
4588 if (stable) {
4589 if (prc.stableCount == 0) {
4590 if (DEBUG_PROVIDER) Slog.v(TAG,
4591 "releaseProvider: stable ref count already 0, how?");
4592 return false;
4593 }
4594 prc.stableCount -= 1;
4595 if (prc.stableCount == 0) {
4596 // What we do at this point depends on whether there are
4597 // any unstable refs left: if there are, we just tell the
4598 // activity manager to decrement its stable count; if there
4599 // aren't, we need to enqueue this provider to be removed,
4600 // and convert to holding a single unstable ref while
4601 // doing so.
4602 lastRef = prc.unstableCount == 0;
4603 try {
4604 if (DEBUG_PROVIDER) {
4605 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef="
4606 + lastRef + " - " + prc.holder.info.name);
4607 }
4608 ActivityManagerNative.getDefault().refContentProvider(
4609 prc.holder.connection, -1, lastRef ? 1 : 0);
4610 } catch (RemoteException e) {
4611 //do nothing content provider object is dead any way
4612 }
4613 }
4614 } else {
4615 if (prc.unstableCount == 0) {
4616 if (DEBUG_PROVIDER) Slog.v(TAG,
4617 "releaseProvider: unstable ref count already 0, how?");
4618 return false;
4619 }
4620 prc.unstableCount -= 1;
4621 if (prc.unstableCount == 0) {
4622 // If this is the last reference, we need to enqueue
4623 // this provider to be removed instead of telling the
4624 // activity manager to remove it at this point.
4625 lastRef = prc.stableCount == 0;
4626 if (!lastRef) {
4627 try {
4628 if (DEBUG_PROVIDER) {
4629 Slog.v(TAG, "releaseProvider: No longer unstable - "
4630 + prc.holder.info.name);
4631 }
4632 ActivityManagerNative.getDefault().refContentProvider(
4633 prc.holder.connection, 0, -1);
4634 } catch (RemoteException e) {
4635 //do nothing content provider object is dead any way
4636 }
4637 }
4638 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004639 }
4640
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004641 if (lastRef) {
4642 if (!prc.removePending) {
4643 // Schedule the actual remove asynchronously, since we don't know the context
4644 // this will be called in.
4645 // TODO: it would be nice to post a delayed message, so
4646 // if we come back and need the same provider quickly
4647 // we will still have it available.
4648 if (DEBUG_PROVIDER) {
4649 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - "
4650 + prc.holder.info.name);
4651 }
4652 prc.removePending = true;
4653 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc);
4654 mH.sendMessage(msg);
4655 } else {
4656 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name);
4657 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004658 }
4659 return true;
4660 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004661 }
4662
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004663 final void completeRemoveProvider(ProviderRefCount prc) {
4664 synchronized (mProviderMap) {
4665 if (!prc.removePending) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004666 // There was a race! Some other client managed to acquire
4667 // the provider before the removal was completed.
4668 // Abort the removal. We will do it later.
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004669 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, "
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004670 + "provider still in use");
4671 return;
4672 }
4673
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004674 final IBinder jBinder = prc.holder.provider.asBinder();
4675 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder);
4676 if (existingPrc == prc) {
4677 mProviderRefCountMap.remove(jBinder);
4678 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004679
4680 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
4681 while (iter.hasNext()) {
4682 ProviderClientRecord pr = iter.next();
4683 IBinder myBinder = pr.mProvider.asBinder();
4684 if (myBinder == jBinder) {
4685 iter.remove();
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004686 }
4687 }
4688 }
4689
4690 try {
4691 if (DEBUG_PROVIDER) {
4692 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
4693 + "removeContentProvider(" + prc.holder.info.name + ")");
4694 }
4695 ActivityManagerNative.getDefault().removeContentProvider(
4696 prc.holder.connection, false);
4697 } catch (RemoteException e) {
4698 //do nothing content provider object is dead any way
4699 }
4700 }
4701
4702 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) {
Dianne Hackbornc428aae2012-10-03 16:38:22 -07004703 synchronized (mProviderMap) {
4704 handleUnstableProviderDiedLocked(provider, fromClient);
4705 }
4706 }
4707
4708 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) {
4709 ProviderRefCount prc = mProviderRefCountMap.get(provider);
4710 if (prc != null) {
4711 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider "
4712 + provider + " " + prc.holder.info.name);
4713 mProviderRefCountMap.remove(provider);
4714 if (prc.client != null && prc.client.mNames != null) {
4715 for (String name : prc.client.mNames) {
4716 ProviderClientRecord pr = mProviderMap.get(name);
4717 if (pr != null && pr.mProvider.asBinder() == provider) {
4718 Slog.i(TAG, "Removing dead content provider: " + name);
4719 mProviderMap.remove(name);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004720 }
4721 }
Dianne Hackbornc428aae2012-10-03 16:38:22 -07004722 }
4723 if (fromClient) {
4724 // We found out about this due to execution in our client
4725 // code. Tell the activity manager about it now, to ensure
4726 // that the next time we go to do anything with the provider
4727 // it knows it is dead (so we don't race with its death
4728 // notification).
4729 try {
4730 ActivityManagerNative.getDefault().unstableProviderDied(
4731 prc.holder.connection);
4732 } catch (RemoteException e) {
4733 //do nothing content provider object is dead any way
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004734 }
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07004735 }
4736 }
4737 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004738
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004739 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
Jeff Sharkey6d515712012-09-20 16:06:08 -07004740 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4741 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4742 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4743
4744 final ProviderClientRecord pcr = new ProviderClientRecord(
4745 auths, provider, localProvider, holder);
4746 for (String auth : auths) {
4747 final ProviderKey key = new ProviderKey(auth, userId);
4748 final ProviderClientRecord existing = mProviderMap.get(key);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004749 if (existing != null) {
4750 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name
Jeff Sharkey6d515712012-09-20 16:06:08 -07004751 + " already published as " + auth);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004752 } else {
Jeff Sharkey6d515712012-09-20 16:06:08 -07004753 mProviderMap.put(key, pcr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004754 }
4755 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004756 return pcr;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004757 }
4758
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004759 /**
4760 * Installs the provider.
4761 *
4762 * Providers that are local to the process or that come from the system server
4763 * may be installed permanently which is indicated by setting noReleaseNeeded to true.
4764 * Other remote providers are reference counted. The initial reference count
4765 * for all reference counted providers is one. Providers that are not reference
4766 * counted do not have a reference count (at all).
4767 *
4768 * This method detects when a provider has already been installed. When this happens,
4769 * it increments the reference count of the existing provider (if appropriate)
4770 * and returns the existing provider. This can happen due to concurrent
4771 * attempts to acquire the same provider.
4772 */
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004773 private IActivityManager.ContentProviderHolder installProvider(Context context,
4774 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4775 boolean noisy, boolean noReleaseNeeded, boolean stable) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004776 ContentProvider localProvider = null;
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004777 IContentProvider provider;
Dianne Hackborn5f48fca2012-05-30 11:06:31 -07004778 if (holder == null || holder.provider == null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004779 if (DEBUG_PROVIDER || noisy) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004780 Slog.d(TAG, "Loading provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004781 + info.name);
4782 }
4783 Context c = null;
4784 ApplicationInfo ai = info.applicationInfo;
4785 if (context.getPackageName().equals(ai.packageName)) {
4786 c = context;
4787 } else if (mInitialApplication != null &&
4788 mInitialApplication.getPackageName().equals(ai.packageName)) {
4789 c = mInitialApplication;
4790 } else {
4791 try {
4792 c = context.createPackageContext(ai.packageName,
4793 Context.CONTEXT_INCLUDE_CODE);
4794 } catch (PackageManager.NameNotFoundException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07004795 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004796 }
4797 }
4798 if (c == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004799 Slog.w(TAG, "Unable to get context for package " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004800 ai.packageName +
4801 " while loading content provider " +
4802 info.name);
4803 return null;
4804 }
4805 try {
4806 final java.lang.ClassLoader cl = c.getClassLoader();
4807 localProvider = (ContentProvider)cl.
4808 loadClass(info.name).newInstance();
4809 provider = localProvider.getIContentProvider();
4810 if (provider == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004811 Slog.e(TAG, "Failed to instantiate class " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004812 info.name + " from sourceDir " +
4813 info.applicationInfo.sourceDir);
4814 return null;
4815 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004816 if (DEBUG_PROVIDER) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004817 TAG, "Instantiating local provider " + info.name);
4818 // XXX Need to create the correct context for this provider.
4819 localProvider.attachInfo(c, info);
4820 } catch (java.lang.Exception e) {
4821 if (!mInstrumentation.onException(null, e)) {
4822 throw new RuntimeException(
4823 "Unable to get provider " + info.name
4824 + ": " + e.toString(), e);
4825 }
4826 return null;
4827 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004828 } else {
4829 provider = holder.provider;
4830 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004831 + info.name);
4832 }
4833
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004834 IActivityManager.ContentProviderHolder retHolder;
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004835
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004836 synchronized (mProviderMap) {
4837 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider
4838 + " / " + info.name);
4839 IBinder jBinder = provider.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004840 if (localProvider != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004841 ComponentName cname = new ComponentName(info.packageName, info.name);
4842 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004843 if (pr != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004844 if (DEBUG_PROVIDER) {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004845 Slog.v(TAG, "installProvider: lost the race, "
4846 + "using existing local provider");
4847 }
4848 provider = pr.mProvider;
4849 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004850 holder = new IActivityManager.ContentProviderHolder(info);
4851 holder.provider = provider;
4852 holder.noReleaseNeeded = true;
4853 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004854 mLocalProviders.put(jBinder, pr);
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004855 mLocalProvidersByName.put(cname, pr);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004856 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004857 retHolder = pr.mHolder;
4858 } else {
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004859 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
4860 if (prc != null) {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004861 if (DEBUG_PROVIDER) {
4862 Slog.v(TAG, "installProvider: lost the race, updating ref count");
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004863 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004864 // We need to transfer our new reference to the existing
4865 // ref count, releasing the old one... but only if
4866 // release is needed (that is, it is not running in the
4867 // system process).
4868 if (!noReleaseNeeded) {
4869 incProviderRefLocked(prc, stable);
4870 try {
4871 ActivityManagerNative.getDefault().removeContentProvider(
4872 holder.connection, stable);
4873 } catch (RemoteException e) {
4874 //do nothing content provider object is dead any way
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004875 }
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004876 }
4877 } else {
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004878 ProviderClientRecord client = installProviderAuthoritiesLocked(
4879 provider, localProvider, holder);
4880 if (noReleaseNeeded) {
4881 prc = new ProviderRefCount(holder, client, 1000, 1000);
4882 } else {
4883 prc = stable
4884 ? new ProviderRefCount(holder, client, 1, 0)
4885 : new ProviderRefCount(holder, client, 0, 1);
4886 }
4887 mProviderRefCountMap.put(jBinder, prc);
Jeff Brownddaa9ac2011-11-11 20:16:14 -08004888 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004889 retHolder = prc.holder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004890 }
4891 }
Dianne Hackborn6ae8d182012-05-23 13:12:42 -07004892
4893 return retHolder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004894 }
4895
Romain Guy65b345f2011-07-27 18:51:50 -07004896 private void attach(boolean system) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004897 sThreadLocal.set(this);
4898 mSystemThread = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004899 if (!system) {
Dianne Hackborn6dd005b2011-07-18 13:22:50 -07004900 ViewRootImpl.addFirstDrawHandler(new Runnable() {
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08004901 public void run() {
4902 ensureJitEnabled();
4903 }
4904 });
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004905 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
4906 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004907 RuntimeInit.setApplicationObject(mAppThread.asBinder());
4908 IActivityManager mgr = ActivityManagerNative.getDefault();
4909 try {
4910 mgr.attachApplication(mAppThread);
4911 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07004912 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004913 }
4914 } else {
4915 // Don't set application object here -- if the system crashes,
4916 // we can't display an alert, we just want to die die die.
Siva Velusamyd693dfa2012-09-10 14:36:58 -07004917 android.ddm.DdmHandleAppName.setAppName("system_process",
4918 UserHandle.myUserId());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004919 try {
4920 mInstrumentation = new Instrumentation();
Dianne Hackborn21556372010-02-04 16:34:40 -08004921 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004922 context.init(getSystemContext().mPackageInfo, null, this);
4923 Application app = Instrumentation.newApplication(Application.class, context);
4924 mAllApplications.add(app);
4925 mInitialApplication = app;
4926 app.onCreate();
4927 } catch (Exception e) {
4928 throw new RuntimeException(
4929 "Unable to instantiate Application():" + e.toString(), e);
4930 }
4931 }
Geremy Condrab7faaf42012-09-19 18:07:42 -07004932
4933 // add dropbox logging to libcore
4934 DropBox.setReporter(new DropBoxReporter());
4935
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004936 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004937 public void onConfigurationChanged(Configuration newConfig) {
4938 synchronized (mPackages) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004939 // We need to apply this change to the resources
4940 // immediately, because upon returning the view
4941 // hierarchy will be informed about it.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004942 if (applyConfigurationToResourcesLocked(newConfig, null)) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004943 // This actually changed the resources! Tell
4944 // everyone about it.
4945 if (mPendingConfiguration == null ||
4946 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
4947 mPendingConfiguration = newConfig;
4948
4949 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
4950 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004951 }
4952 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004953 }
4954 public void onLowMemory() {
4955 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004956 public void onTrimMemory(int level) {
4957 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004958 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004959 }
4960
Romain Guy5e9120d2012-01-30 12:17:22 -08004961 public static ActivityThread systemMain() {
Dianne Hackborn5d927c22011-09-02 12:22:18 -07004962 HardwareRenderer.disable(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004963 ActivityThread thread = new ActivityThread();
4964 thread.attach(true);
4965 return thread;
4966 }
4967
Jeff Brown10e89712011-07-08 18:52:57 -07004968 public final void installSystemProviders(List<ProviderInfo> providers) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004969 if (providers != null) {
Jeff Brown10e89712011-07-08 18:52:57 -07004970 installContentProviders(mInitialApplication, providers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004971 }
4972 }
4973
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004974 public int getIntCoreSetting(String key, int defaultValue) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08004975 synchronized (mPackages) {
4976 if (mCoreSettings != null) {
4977 return mCoreSettings.getInt(key, defaultValue);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004978 } else {
4979 return defaultValue;
4980 }
4981 }
4982 }
4983
Geremy Condra69689a72012-09-11 16:57:17 -07004984 private static class EventLoggingReporter implements EventLogger.Reporter {
4985 @Override
4986 public void report (int code, Object... list) {
4987 EventLog.writeEvent(code, list);
4988 }
4989 }
4990
Geremy Condrab7faaf42012-09-19 18:07:42 -07004991 private class DropBoxReporter implements DropBox.Reporter {
4992
4993 private DropBoxManager dropBox;
4994
4995 public DropBoxReporter() {
4996 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
4997 }
4998
4999 @Override
5000 public void addData(String tag, byte[] data, int flags) {
5001 dropBox.addData(tag, data, flags);
5002 }
5003
5004 @Override
5005 public void addText(String tag, String data) {
5006 dropBox.addText(tag, data);
5007 }
5008 }
5009
Romain Guy65b345f2011-07-27 18:51:50 -07005010 public static void main(String[] args) {
Bob Leee5408332009-09-04 18:31:17 -07005011 SamplingProfilerIntegration.start();
5012
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -08005013 // CloseGuard defaults to true and can be quite spammy. We
5014 // disable it here, but selectively enable it later (via
5015 // StrictMode) on debug builds, but using DropBox, not logs.
5016 CloseGuard.setEnabled(false);
5017
Jeff Sharkeyb049e212012-09-07 23:16:01 -07005018 Environment.initForCurrentUser();
5019
Geremy Condra69689a72012-09-11 16:57:17 -07005020 // Set the reporter for event logging in libcore
5021 EventLogger.setReporter(new EventLoggingReporter());
5022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005023 Process.setArgV0("<pre-initialized>");
5024
5025 Looper.prepareMainLooper();
5026
5027 ActivityThread thread = new ActivityThread();
5028 thread.attach(false);
5029
Vairavan Srinivasan7335cfd2012-08-18 18:36:03 -07005030 if (sMainThreadHandler == null) {
5031 sMainThreadHandler = thread.getHandler();
5032 }
5033
Romain Guy5e9120d2012-01-30 12:17:22 -08005034 AsyncTask.init();
5035
Dianne Hackborn287952c2010-09-22 22:34:31 -07005036 if (false) {
5037 Looper.myLooper().setMessageLogging(new
5038 LogPrinter(Log.DEBUG, "ActivityThread"));
5039 }
5040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005041 Looper.loop();
5042
Jeff Brown10e89712011-07-08 18:52:57 -07005043 throw new RuntimeException("Main thread loop unexpectedly exited");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005044 }
5045}