blob: 8931675dd914d00624562972482b30cbe764a447 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.app;
18
Christopher Tate45281862010-03-05 15:46:30 -080019import android.app.backup.BackupAgent;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.BroadcastReceiver;
Dianne Hackbornc68c9132011-07-29 01:25:18 -070021import android.content.ComponentCallbacks2;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.ComponentName;
23import android.content.ContentProvider;
24import android.content.Context;
25import android.content.IContentProvider;
26import android.content.Intent;
Suchi Amalapurapu1ccac752009-06-12 10:09:58 -070027import android.content.IIntentReceiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.content.pm.ActivityInfo;
29import android.content.pm.ApplicationInfo;
30import android.content.pm.IPackageManager;
31import android.content.pm.InstrumentationInfo;
32import android.content.pm.PackageManager;
Sen Hubde75702010-05-28 01:54:03 -070033import android.content.pm.PackageManager.NameNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080034import android.content.pm.ProviderInfo;
35import android.content.pm.ServiceInfo;
36import android.content.res.AssetManager;
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -070037import android.content.res.CompatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.content.res.Configuration;
39import android.content.res.Resources;
40import android.database.sqlite.SQLiteDatabase;
41import android.database.sqlite.SQLiteDebug;
Vasu Noric3849202010-03-09 10:47:25 -080042import android.database.sqlite.SQLiteDebug.DbStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043import android.graphics.Bitmap;
44import android.graphics.Canvas;
Robert Greenwalt434203a2010-10-11 16:00:27 -070045import android.net.IConnectivityManager;
46import android.net.Proxy;
47import android.net.ProxyProperties;
Joe Onoratod630f102011-03-17 18:42:26 -070048import android.os.AsyncTask;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080049import android.os.Bundle;
50import android.os.Debug;
51import android.os.Handler;
52import android.os.IBinder;
53import android.os.Looper;
54import android.os.Message;
55import android.os.MessageQueue;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070056import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080057import android.os.Process;
58import android.os.RemoteException;
59import android.os.ServiceManager;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -070060import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.os.SystemClock;
62import android.util.AndroidRuntimeException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.util.DisplayMetrics;
64import android.util.EventLog;
65import android.util.Log;
Dianne Hackborn287952c2010-09-22 22:34:31 -070066import android.util.LogPrinter;
Dianne Hackbornc9421ba2010-03-11 22:23:46 -080067import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.view.Display;
Romain Guy52339202010-09-03 16:04:46 -070069import android.view.HardwareRenderer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070import android.view.View;
71import android.view.ViewDebug;
72import android.view.ViewManager;
Dianne Hackborn6dd005b2011-07-18 13:22:50 -070073import android.view.ViewRootImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074import android.view.Window;
75import android.view.WindowManager;
76import android.view.WindowManagerImpl;
77
78import com.android.internal.os.BinderInternal;
79import com.android.internal.os.RuntimeInit;
Bob Leee5408332009-09-04 18:31:17 -070080import com.android.internal.os.SamplingProfilerIntegration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081
82import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
83
84import java.io.File;
85import java.io.FileDescriptor;
86import java.io.FileOutputStream;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070087import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import java.io.PrintWriter;
89import java.lang.ref.WeakReference;
Robert Greenwalt03595d02010-11-02 14:08:23 -070090import java.net.InetAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import java.util.ArrayList;
92import java.util.HashMap;
93import java.util.Iterator;
94import java.util.List;
95import java.util.Locale;
96import java.util.Map;
97import java.util.TimeZone;
98import java.util.regex.Pattern;
99
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -0800100import dalvik.system.CloseGuard;
Bob Leee5408332009-09-04 18:31:17 -0700101
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102final class SuperNotCalledException extends AndroidRuntimeException {
103 public SuperNotCalledException(String msg) {
104 super(msg);
105 }
106}
107
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700108final class RemoteServiceException extends AndroidRuntimeException {
109 public RemoteServiceException(String msg) {
110 super(msg);
111 }
112}
113
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800114/**
115 * This manages the execution of the main thread in an
116 * application process, scheduling and executing activities,
117 * broadcasts, and other operations on it as the activity
118 * manager requests.
119 *
120 * {@hide}
121 */
122public final class ActivityThread {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700123 /** @hide */
124 public static final String TAG = "ActivityThread";
Jim Miller0b2a6d02010-07-13 18:01:29 -0700125 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
Joe Onorato43a17652011-04-06 19:22:23 -0700126 static final boolean localLOGV = false;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700127 static final boolean DEBUG_MESSAGES = false;
Dianne Hackborne829fef2010-10-26 17:44:01 -0700128 /** @hide */
129 public static final boolean DEBUG_BROADCAST = false;
Chris Tate8a7dc172009-03-24 20:11:42 -0700130 private static final boolean DEBUG_RESULTS = false;
Christopher Tate4a627c72011-04-01 14:43:32 -0700131 private static final boolean DEBUG_BACKUP = true;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700132 private static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
134 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
135 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
136 private static final int LOG_ON_PAUSE_CALLED = 30021;
137 private static final int LOG_ON_RESUME_CALLED = 30022;
138
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700139 static ContextImpl mSystemContext = null;
Bob Leee5408332009-09-04 18:31:17 -0700140
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700141 static IPackageManager sPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700143 final ApplicationThread mAppThread = new ApplicationThread();
144 final Looper mLooper = Looper.myLooper();
145 final H mH = new H();
146 final HashMap<IBinder, ActivityClientRecord> mActivities
147 = new HashMap<IBinder, ActivityClientRecord>();
148 // List of new activities (via ActivityRecord.nextIdle) that should
149 // be reported when next we idle.
150 ActivityClientRecord mNewActivities = null;
151 // Number of activities that are currently visible on-screen.
152 int mNumVisibleActivities = 0;
153 final HashMap<IBinder, Service> mServices
154 = new HashMap<IBinder, Service>();
155 AppBindData mBoundApplication;
156 Configuration mConfiguration;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700157 Configuration mCompatConfiguration;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700158 Configuration mResConfiguration;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700159 CompatibilityInfo mResCompatibilityInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700160 Application mInitialApplication;
161 final ArrayList<Application> mAllApplications
162 = new ArrayList<Application>();
163 // set of instantiated backup agents, keyed by package name
164 final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
Romain Guy65b345f2011-07-27 18:51:50 -0700165 static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700166 Instrumentation mInstrumentation;
167 String mInstrumentationAppDir = null;
168 String mInstrumentationAppPackage = null;
169 String mInstrumentedAppDir = null;
170 boolean mSystemThread = false;
171 boolean mJitEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700173 // These can be accessed by multiple threads; mPackages is the lock.
174 // XXX For now we keep around information about all packages we have
175 // seen, not removing entries from this map.
Dianne Hackborn2f0b1752011-05-31 17:59:49 -0700176 // NOTE: The activity manager in its process needs to call in to
177 // ActivityThread to do things like update resource configurations,
178 // which means this lock gets held while the activity manager holds its
179 // own lock. Thus you MUST NEVER call back into the activity manager
180 // or anything that depends on it while holding this lock.
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700181 final HashMap<String, WeakReference<LoadedApk>> mPackages
182 = new HashMap<String, WeakReference<LoadedApk>>();
183 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
184 = new HashMap<String, WeakReference<LoadedApk>>();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700185 final HashMap<CompatibilityInfo, DisplayMetrics> mDisplayMetrics
186 = new HashMap<CompatibilityInfo, DisplayMetrics>();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700187 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
188 = new HashMap<ResourcesKey, WeakReference<Resources> >();
189 final ArrayList<ActivityClientRecord> mRelaunchingActivities
190 = new ArrayList<ActivityClientRecord>();
191 Configuration mPendingConfiguration = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800192
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700193 // The lock of mProviderMap protects the following variables.
194 final HashMap<String, ProviderClientRecord> mProviderMap
195 = new HashMap<String, ProviderClientRecord>();
196 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
197 = new HashMap<IBinder, ProviderRefCount>();
198 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
199 = new HashMap<IBinder, ProviderClientRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800200
Jeff Hamilton52d32032011-01-08 15:31:26 -0600201 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
202 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
203
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700204 final GcIdler mGcIdler = new GcIdler();
205 boolean mGcIdlerScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700207 static Handler sMainThreadHandler; // set once in main()
208
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800209 Bundle mCoreSettings = null;
210
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400211 static final class ActivityClientRecord {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212 IBinder token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700213 int ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 Intent intent;
215 Bundle state;
216 Activity activity;
217 Window window;
218 Activity parent;
219 String embeddedID;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -0700220 Activity.NonConfigurationInstances lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800221 boolean paused;
222 boolean stopped;
223 boolean hideForNow;
224 Configuration newConfig;
Dianne Hackborne88846e2009-09-30 21:34:25 -0700225 Configuration createdConfig;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700226 ActivityClientRecord nextIdle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800227
228 ActivityInfo activityInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400229 CompatibilityInfo compatInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700230 LoadedApk packageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231
232 List<ResultInfo> pendingResults;
233 List<Intent> pendingIntents;
234
235 boolean startsNotResumed;
236 boolean isForward;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800237 int pendingConfigChanges;
238 boolean onlyLocalRequest;
239
240 View mPendingRemoveWindow;
241 WindowManager mPendingRemoveWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700243 ActivityClientRecord() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800244 parent = null;
245 embeddedID = null;
246 paused = false;
247 stopped = false;
248 hideForNow = false;
249 nextIdle = null;
250 }
251
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800252 public boolean isPreHoneycomb() {
253 if (activity != null) {
254 return activity.getApplicationInfo().targetSdkVersion
255 < android.os.Build.VERSION_CODES.HONEYCOMB;
256 }
257 return false;
258 }
259
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800260 public String toString() {
261 ComponentName componentName = intent.getComponent();
262 return "ActivityRecord{"
263 + Integer.toHexString(System.identityHashCode(this))
264 + " token=" + token + " " + (componentName == null
265 ? "no component name" : componentName.toShortString())
266 + "}";
267 }
268 }
269
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400270 final class ProviderClientRecord implements IBinder.DeathRecipient {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 final String mName;
272 final IContentProvider mProvider;
273 final ContentProvider mLocalProvider;
274
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700275 ProviderClientRecord(String name, IContentProvider provider,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800276 ContentProvider localProvider) {
277 mName = name;
278 mProvider = provider;
279 mLocalProvider = localProvider;
280 }
281
282 public void binderDied() {
283 removeDeadProvider(mName, mProvider);
284 }
285 }
286
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400287 static final class NewIntentData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800288 List<Intent> intents;
289 IBinder token;
290 public String toString() {
291 return "NewIntentData{intents=" + intents + " token=" + token + "}";
292 }
293 }
294
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400295 static final class ReceiverData extends BroadcastReceiver.PendingResult {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700296 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
297 boolean ordered, boolean sticky, IBinder token) {
298 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, token);
299 this.intent = intent;
300 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700301
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800302 Intent intent;
303 ActivityInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400304 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 public String toString() {
306 return "ReceiverData{intent=" + intent + " packageName=" +
Dianne Hackborne829fef2010-10-26 17:44:01 -0700307 info.packageName + " resultCode=" + getResultCode()
308 + " resultData=" + getResultData() + " resultExtras="
309 + getResultExtras(false) + "}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800310 }
311 }
312
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400313 static final class CreateBackupAgentData {
Christopher Tate181fafa2009-05-14 11:12:14 -0700314 ApplicationInfo appInfo;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400315 CompatibilityInfo compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700316 int backupMode;
317 public String toString() {
318 return "CreateBackupAgentData{appInfo=" + appInfo
319 + " backupAgent=" + appInfo.backupAgentName
320 + " mode=" + backupMode + "}";
321 }
322 }
Bob Leee5408332009-09-04 18:31:17 -0700323
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400324 static final class CreateServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800325 IBinder token;
326 ServiceInfo info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400327 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328 Intent intent;
329 public String toString() {
330 return "CreateServiceData{token=" + token + " className="
331 + info.name + " packageName=" + info.packageName
332 + " intent=" + intent + "}";
333 }
334 }
335
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400336 static final class BindServiceData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 IBinder token;
338 Intent intent;
339 boolean rebind;
340 public String toString() {
341 return "BindServiceData{token=" + token + " intent=" + intent + "}";
342 }
343 }
344
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400345 static final class ServiceArgsData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800346 IBinder token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700347 boolean taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800348 int startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700349 int flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800350 Intent args;
351 public String toString() {
352 return "ServiceArgsData{token=" + token + " startId=" + startId
353 + " args=" + args + "}";
354 }
355 }
356
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400357 static final class AppBindData {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700358 LoadedApk info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 String processName;
360 ApplicationInfo appInfo;
361 List<ProviderInfo> providers;
362 ComponentName instrumentationName;
363 String profileFile;
364 Bundle instrumentationArgs;
365 IInstrumentationWatcher instrumentationWatcher;
366 int debugMode;
Christopher Tate181fafa2009-05-14 11:12:14 -0700367 boolean restrictedBackupMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368 Configuration config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400369 CompatibilityInfo compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 boolean handlingProfiling;
371 public String toString() {
372 return "AppBindData{appInfo=" + appInfo + "}";
373 }
374 }
375
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400376 static final class DumpComponentInfo {
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700377 ParcelFileDescriptor fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700378 IBinder token;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800379 String prefix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800380 String[] args;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 }
382
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400383 static final class ResultData {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384 IBinder token;
385 List<ResultInfo> results;
386 public String toString() {
387 return "ResultData{token=" + token + " results" + results + "}";
388 }
389 }
390
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400391 static final class ContextCleanupInfo {
Dianne Hackborn21556372010-02-04 16:34:40 -0800392 ContextImpl context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393 String what;
394 String who;
395 }
396
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400397 static final class ProfilerControlData {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700398 String path;
399 ParcelFileDescriptor fd;
400 }
401
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400402 static final class DumpHeapData {
Andy McFadden824c5102010-07-09 16:26:57 -0700403 String path;
404 ParcelFileDescriptor fd;
405 }
406
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400407 static final class UpdateCompatibilityData {
408 String pkg;
409 CompatibilityInfo info;
410 }
Dianne Hackbornaa9d84c2011-05-09 19:00:59 -0700411
Romain Guy65b345f2011-07-27 18:51:50 -0700412 private native void dumpGraphicsInfo(FileDescriptor fd);
Chet Haase9c1e23b2011-03-24 10:51:31 -0700413
Romain Guy65b345f2011-07-27 18:51:50 -0700414 private class ApplicationThread extends ApplicationThreadNative {
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700415 private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
416 private static final String ONE_COUNT_COLUMN = "%21s %8d";
417 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
418 private static final String TWO_COUNT_COLUMNS_DB = "%21s %8d %21s %8d";
Vasu Nori3c7131f2010-09-21 14:36:57 -0700419 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
Bob Leee5408332009-09-04 18:31:17 -0700420
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 // Formatting for checkin service - update version if row format changes
422 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
Bob Leee5408332009-09-04 18:31:17 -0700423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 public final void schedulePauseActivity(IBinder token, boolean finished,
425 boolean userLeaving, int configChanges) {
426 queueOrSendMessage(
427 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
428 token,
429 (userLeaving ? 1 : 0),
430 configChanges);
431 }
432
433 public final void scheduleStopActivity(IBinder token, boolean showWindow,
434 int configChanges) {
435 queueOrSendMessage(
436 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
437 token, 0, configChanges);
438 }
439
440 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
441 queueOrSendMessage(
442 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
443 token);
444 }
445
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800446 public final void scheduleSleeping(IBinder token, boolean sleeping) {
447 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
448 }
449
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800450 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
451 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
452 }
453
454 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
455 ResultData res = new ResultData();
456 res.token = token;
457 res.results = results;
458 queueOrSendMessage(H.SEND_RESULT, res);
459 }
460
461 // we use token to identify this activity without having to send the
462 // activity itself back to the activity manager. (matters more with ipc)
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700463 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400464 ActivityInfo info, CompatibilityInfo compatInfo, Bundle state,
465 List<ResultInfo> pendingResults,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800466 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700467 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800468
469 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700470 r.ident = ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 r.intent = intent;
472 r.activityInfo = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400473 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800474 r.state = state;
475
476 r.pendingResults = pendingResults;
477 r.pendingIntents = pendingNewIntents;
478
479 r.startsNotResumed = notResumed;
480 r.isForward = isForward;
481
482 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
483 }
484
485 public final void scheduleRelaunchActivity(IBinder token,
486 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
Dianne Hackborn871ecdc2009-12-11 15:24:33 -0800487 int configChanges, boolean notResumed, Configuration config) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800488 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
489 configChanges, notResumed, config, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800490 }
491
492 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
493 NewIntentData data = new NewIntentData();
494 data.intents = intents;
495 data.token = token;
496
497 queueOrSendMessage(H.NEW_INTENT, data);
498 }
499
500 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
501 int configChanges) {
502 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
503 configChanges);
504 }
505
506 public final void scheduleReceiver(Intent intent, ActivityInfo info,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400507 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
508 boolean sync) {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700509 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
510 sync, false, mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 r.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400512 r.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 queueOrSendMessage(H.RECEIVER, r);
514 }
515
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400516 public final void scheduleCreateBackupAgent(ApplicationInfo app,
517 CompatibilityInfo compatInfo, int backupMode) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700518 CreateBackupAgentData d = new CreateBackupAgentData();
519 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400520 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700521 d.backupMode = backupMode;
522
523 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
524 }
525
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400526 public final void scheduleDestroyBackupAgent(ApplicationInfo app,
527 CompatibilityInfo compatInfo) {
Christopher Tate181fafa2009-05-14 11:12:14 -0700528 CreateBackupAgentData d = new CreateBackupAgentData();
529 d.appInfo = app;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400530 d.compatInfo = compatInfo;
Christopher Tate181fafa2009-05-14 11:12:14 -0700531
532 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
533 }
534
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800535 public final void scheduleCreateService(IBinder token,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400536 ServiceInfo info, CompatibilityInfo compatInfo) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800537 CreateServiceData s = new CreateServiceData();
538 s.token = token;
539 s.info = info;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400540 s.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541
542 queueOrSendMessage(H.CREATE_SERVICE, s);
543 }
544
545 public final void scheduleBindService(IBinder token, Intent intent,
546 boolean rebind) {
547 BindServiceData s = new BindServiceData();
548 s.token = token;
549 s.intent = intent;
550 s.rebind = rebind;
551
552 queueOrSendMessage(H.BIND_SERVICE, s);
553 }
554
555 public final void scheduleUnbindService(IBinder token, Intent intent) {
556 BindServiceData s = new BindServiceData();
557 s.token = token;
558 s.intent = intent;
559
560 queueOrSendMessage(H.UNBIND_SERVICE, s);
561 }
562
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700563 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId,
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700564 int flags ,Intent args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 ServiceArgsData s = new ServiceArgsData();
566 s.token = token;
Dianne Hackborn0c5001d2011-04-12 18:16:08 -0700567 s.taskRemoved = taskRemoved;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 s.startId = startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700569 s.flags = flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800570 s.args = args;
571
572 queueOrSendMessage(H.SERVICE_ARGS, s);
573 }
574
575 public final void scheduleStopService(IBinder token) {
576 queueOrSendMessage(H.STOP_SERVICE, token);
577 }
578
579 public final void bindApplication(String processName,
580 ApplicationInfo appInfo, List<ProviderInfo> providers,
581 ComponentName instrumentationName, String profileFile,
582 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
Christopher Tate181fafa2009-05-14 11:12:14 -0700583 int debugMode, boolean isRestrictedBackupMode, Configuration config,
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400584 CompatibilityInfo compatInfo, Map<String, IBinder> services,
585 Bundle coreSettings) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800586
587 if (services != null) {
588 // Setup the service cache in the ServiceManager
589 ServiceManager.initServiceCache(services);
590 }
591
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800592 setCoreSettings(coreSettings);
593
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 AppBindData data = new AppBindData();
595 data.processName = processName;
596 data.appInfo = appInfo;
597 data.providers = providers;
598 data.instrumentationName = instrumentationName;
599 data.profileFile = profileFile;
600 data.instrumentationArgs = instrumentationArgs;
601 data.instrumentationWatcher = instrumentationWatcher;
602 data.debugMode = debugMode;
Christopher Tate181fafa2009-05-14 11:12:14 -0700603 data.restrictedBackupMode = isRestrictedBackupMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800604 data.config = config;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400605 data.compatInfo = compatInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 queueOrSendMessage(H.BIND_APPLICATION, data);
607 }
608
609 public final void scheduleExit() {
610 queueOrSendMessage(H.EXIT_APPLICATION, null);
611 }
612
Christopher Tate5e1ab332009-09-01 20:32:49 -0700613 public final void scheduleSuicide() {
614 queueOrSendMessage(H.SUICIDE, null);
615 }
616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 public void requestThumbnail(IBinder token) {
618 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
619 }
620
621 public void scheduleConfigurationChanged(Configuration config) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800622 synchronized (mPackages) {
623 if (mPendingConfiguration == null ||
624 mPendingConfiguration.isOtherSeqNewer(config)) {
625 mPendingConfiguration = config;
626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800627 }
628 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
629 }
630
631 public void updateTimeZone() {
632 TimeZone.setDefault(null);
633 }
634
Robert Greenwalt03595d02010-11-02 14:08:23 -0700635 public void clearDnsCache() {
636 // a non-standard API to get this to libcore
637 InetAddress.clearDnsCache();
638 }
639
Robert Greenwalt434203a2010-10-11 16:00:27 -0700640 public void setHttpProxy(String host, String port, String exclList) {
641 Proxy.setHttpProxySystemProperty(host, port, exclList);
642 }
643
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800644 public void processInBackground() {
645 mH.removeMessages(H.GC_WHEN_IDLE);
646 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
647 }
648
649 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700650 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700651 try {
652 data.fd = ParcelFileDescriptor.dup(fd);
653 data.token = servicetoken;
654 data.args = args;
655 queueOrSendMessage(H.DUMP_SERVICE, data);
656 } catch (IOException e) {
657 Slog.w(TAG, "dumpService failed", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800658 }
659 }
660
661 // This function exists to make sure all receiver dispatching is
662 // correctly ordered, since these are one-way calls and the binder driver
663 // applies transaction ordering per object for such calls.
664 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
Dianne Hackborn68d881c2009-10-05 13:58:17 -0700665 int resultCode, String dataStr, Bundle extras, boolean ordered,
666 boolean sticky) throws RemoteException {
667 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800668 }
Bob Leee5408332009-09-04 18:31:17 -0700669
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800670 public void scheduleLowMemory() {
671 queueOrSendMessage(H.LOW_MEMORY, null);
672 }
673
674 public void scheduleActivityConfigurationChanged(IBinder token) {
675 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
676 }
677
Romain Guy7eabe552011-07-21 14:56:34 -0700678 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd,
679 int profileType) {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700680 ProfilerControlData pcd = new ProfilerControlData();
681 pcd.path = path;
682 pcd.fd = fd;
Romain Guy7eabe552011-07-21 14:56:34 -0700683 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800684 }
685
Andy McFadden824c5102010-07-09 16:26:57 -0700686 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
687 DumpHeapData dhd = new DumpHeapData();
688 dhd.path = path;
689 dhd.fd = fd;
690 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
691 }
692
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700693 public void setSchedulingGroup(int group) {
694 // Note: do this immediately, since going into the foreground
695 // should happen regardless of what pending work we have to do
696 // and the activity manager will wait for us to report back that
697 // we are done before sending us to the background.
698 try {
699 Process.setProcessGroup(Process.myPid(), group);
700 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800701 Slog.w(TAG, "Failed setting process group to " + group, e);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700702 }
703 }
Bob Leee5408332009-09-04 18:31:17 -0700704
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700705 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
706 Debug.getMemoryInfo(outInfo);
707 }
Bob Leee5408332009-09-04 18:31:17 -0700708
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700709 public void dispatchPackageBroadcast(int cmd, String[] packages) {
710 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
711 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700712
713 public void scheduleCrash(String msg) {
714 queueOrSendMessage(H.SCHEDULE_CRASH, msg);
715 }
Dianne Hackborn625ac272010-09-17 18:29:22 -0700716
Dianne Hackborn30d71892010-12-11 10:37:55 -0800717 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
718 String prefix, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700719 DumpComponentInfo data = new DumpComponentInfo();
Dianne Hackborne17aeb32011-04-07 15:11:57 -0700720 try {
721 data.fd = ParcelFileDescriptor.dup(fd);
722 data.token = activitytoken;
723 data.prefix = prefix;
724 data.args = args;
725 queueOrSendMessage(H.DUMP_ACTIVITY, data);
726 } catch (IOException e) {
727 Slog.w(TAG, "dumpActivity failed", e);
Dianne Hackborn625ac272010-09-17 18:29:22 -0700728 }
729 }
Chet Haase9c1e23b2011-03-24 10:51:31 -0700730
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 @Override
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700732 public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, String[] args) {
733 FileOutputStream fout = new FileOutputStream(fd);
734 PrintWriter pw = new PrintWriter(fout);
735 try {
Romain Guy65b345f2011-07-27 18:51:50 -0700736 return dumpMemInfo(pw, args);
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700737 } finally {
Chet Haase9c1e23b2011-03-24 10:51:31 -0700738 pw.flush();
Chet Haase9c1e23b2011-03-24 10:51:31 -0700739 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700740 }
741
Romain Guy65b345f2011-07-27 18:51:50 -0700742 private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, String[] args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800743 long nativeMax = Debug.getNativeHeapSize() / 1024;
744 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
745 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
746
747 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
748 Debug.getMemoryInfo(memInfo);
749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 Runtime runtime = Runtime.getRuntime();
751
752 long dalvikMax = runtime.totalMemory() / 1024;
753 long dalvikFree = runtime.freeMemory() / 1024;
754 long dalvikAllocated = dalvikMax - dalvikFree;
755 long viewInstanceCount = ViewDebug.getViewInstanceCount();
Romain Guy65b345f2011-07-27 18:51:50 -0700756 long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
Brian Carlstromc21550a2010-10-05 21:34:06 -0700757 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
758 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800759 int globalAssetCount = AssetManager.getGlobalAssetCount();
760 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
761 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
762 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
763 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
Brian Carlstromc9d5b312010-10-05 22:23:41 -0700764 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 long sqliteAllocated = SQLiteDebug.getHeapAllocatedSize() / 1024;
Vasu Noric3849202010-03-09 10:47:25 -0800766 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
Bob Leee5408332009-09-04 18:31:17 -0700767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 // Check to see if we were called by checkin server. If so, print terse format.
769 boolean doCheckinFormat = false;
770 if (args != null) {
771 for (String arg : args) {
772 if ("-c".equals(arg)) doCheckinFormat = true;
773 }
774 }
Bob Leee5408332009-09-04 18:31:17 -0700775
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 // For checkin, we print one long comma-separated list of values
777 if (doCheckinFormat) {
778 // NOTE: if you change anything significant below, also consider changing
779 // ACTIVITY_THREAD_CHECKIN_VERSION.
Bob Leee5408332009-09-04 18:31:17 -0700780 String processName = (mBoundApplication != null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800781 ? mBoundApplication.processName : "unknown";
Bob Leee5408332009-09-04 18:31:17 -0700782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 // Header
784 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
785 pw.print(Process.myPid()); pw.print(',');
786 pw.print(processName); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800788 // Heap info - max
789 pw.print(nativeMax); pw.print(',');
790 pw.print(dalvikMax); pw.print(',');
791 pw.print("N/A,");
792 pw.print(nativeMax + dalvikMax); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 // Heap info - allocated
795 pw.print(nativeAllocated); pw.print(',');
796 pw.print(dalvikAllocated); pw.print(',');
797 pw.print("N/A,");
798 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800800 // Heap info - free
801 pw.print(nativeFree); pw.print(',');
802 pw.print(dalvikFree); pw.print(',');
803 pw.print("N/A,");
804 pw.print(nativeFree + dalvikFree); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 // Heap info - proportional set size
807 pw.print(memInfo.nativePss); pw.print(',');
808 pw.print(memInfo.dalvikPss); pw.print(',');
809 pw.print(memInfo.otherPss); pw.print(',');
810 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700811
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800812 // Heap info - shared
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700813 pw.print(memInfo.nativeSharedDirty); pw.print(',');
814 pw.print(memInfo.dalvikSharedDirty); pw.print(',');
815 pw.print(memInfo.otherSharedDirty); pw.print(',');
816 pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty
817 + memInfo.otherSharedDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 // Heap info - private
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700820 pw.print(memInfo.nativePrivateDirty); pw.print(',');
821 pw.print(memInfo.dalvikPrivateDirty); pw.print(',');
822 pw.print(memInfo.otherPrivateDirty); pw.print(',');
823 pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty
824 + memInfo.otherPrivateDirty); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700825
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 // Object counts
827 pw.print(viewInstanceCount); pw.print(',');
828 pw.print(viewRootInstanceCount); pw.print(',');
829 pw.print(appContextInstanceCount); pw.print(',');
830 pw.print(activityInstanceCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700831
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800832 pw.print(globalAssetCount); pw.print(',');
833 pw.print(globalAssetManagerCount); pw.print(',');
834 pw.print(binderLocalObjectCount); pw.print(',');
835 pw.print(binderProxyObjectCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700836
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800837 pw.print(binderDeathObjectCount); pw.print(',');
838 pw.print(openSslSocketCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800840 // SQL
841 pw.print(sqliteAllocated); pw.print(',');
Vasu Noric3849202010-03-09 10:47:25 -0800842 pw.print(stats.memoryUsed / 1024); pw.print(',');
843 pw.print(stats.pageCacheOverflo / 1024); pw.print(',');
844 pw.print(stats.largestMemAlloc / 1024); pw.print(',');
845 for (int i = 0; i < stats.dbStats.size(); i++) {
846 DbStats dbStats = stats.dbStats.get(i);
847 printRow(pw, DB_INFO_FORMAT, dbStats.pageSize, dbStats.dbSize,
Vasu Nori90a367262010-04-12 12:49:09 -0700848 dbStats.lookaside, dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -0800849 pw.print(',');
850 }
Bob Leee5408332009-09-04 18:31:17 -0700851
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700852 return memInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800853 }
Bob Leee5408332009-09-04 18:31:17 -0700854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 // otherwise, show human-readable format
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700856 printRow(pw, HEAP_COLUMN, "", "", "Shared", "Private", "Heap", "Heap", "Heap");
857 printRow(pw, HEAP_COLUMN, "", "Pss", "Dirty", "Dirty", "Size", "Alloc", "Free");
858 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------",
859 "------");
860 printRow(pw, HEAP_COLUMN, "Native", memInfo.nativePss, memInfo.nativeSharedDirty,
861 memInfo.nativePrivateDirty, nativeMax, nativeAllocated, nativeFree);
862 printRow(pw, HEAP_COLUMN, "Dalvik", memInfo.dalvikPss, memInfo.dalvikSharedDirty,
863 memInfo.dalvikPrivateDirty, dalvikMax, dalvikAllocated, dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700865 int otherPss = memInfo.otherPss;
866 int otherSharedDirty = memInfo.otherSharedDirty;
867 int otherPrivateDirty = memInfo.otherPrivateDirty;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800868
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700869 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
Romain Guy65b345f2011-07-27 18:51:50 -0700870 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700871 memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
872 memInfo.getOtherPrivateDirty(i), "", "", "");
873 otherPss -= memInfo.getOtherPss(i);
874 otherSharedDirty -= memInfo.getOtherSharedDirty(i);
875 otherPrivateDirty -= memInfo.getOtherPrivateDirty(i);
876 }
877
878 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSharedDirty,
879 otherPrivateDirty, "", "", "");
880 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(),
881 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(),
882 nativeMax+dalvikMax, nativeAllocated+dalvikAllocated,
883 nativeFree+dalvikFree);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884
885 pw.println(" ");
886 pw.println(" Objects");
Romain Guy65b345f2011-07-27 18:51:50 -0700887 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 viewRootInstanceCount);
889
890 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
891 "Activities:", activityInstanceCount);
892
893 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
894 "AssetManagers:", globalAssetManagerCount);
895
896 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
897 "Proxy Binders:", binderProxyObjectCount);
898 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
899
900 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
Bob Leee5408332009-09-04 18:31:17 -0700901
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800902 // SQLite mem info
903 pw.println(" ");
904 pw.println(" SQL");
Vasu Nori3c7131f2010-09-21 14:36:57 -0700905 printRow(pw, TWO_COUNT_COLUMNS_DB, "heap:", sqliteAllocated, "MEMORY_USED:",
Vasu Noric3849202010-03-09 10:47:25 -0800906 stats.memoryUsed / 1024);
Vasu Nori3c7131f2010-09-21 14:36:57 -0700907 printRow(pw, TWO_COUNT_COLUMNS_DB, "PAGECACHE_OVERFLOW:",
908 stats.pageCacheOverflo / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -0800909 pw.println(" ");
910 int N = stats.dbStats.size();
911 if (N > 0) {
912 pw.println(" DATABASES");
Vasu Nori3c7131f2010-09-21 14:36:57 -0700913 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
914 "Dbname");
Vasu Noric3849202010-03-09 10:47:25 -0800915 for (int i = 0; i < N; i++) {
916 DbStats dbStats = stats.dbStats.get(i);
Vasu Nori3c7131f2010-09-21 14:36:57 -0700917 printRow(pw, DB_INFO_FORMAT,
918 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
919 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
920 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
921 dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -0800922 }
923 }
Bob Leee5408332009-09-04 18:31:17 -0700924
Dianne Hackborn82e1ee92009-08-11 18:56:41 -0700925 // Asset details.
926 String assetAlloc = AssetManager.getAssetAllocations();
927 if (assetAlloc != null) {
928 pw.println(" ");
929 pw.println(" Asset Allocations");
930 pw.print(assetAlloc);
931 }
Dianne Hackborn0e3328f2011-07-17 13:31:17 -0700932
933 return memInfo;
934 }
935
936 @Override
937 public void dumpGfxInfo(FileDescriptor fd, String[] args) {
938 dumpGraphicsInfo(fd);
Romain Guy65b345f2011-07-27 18:51:50 -0700939 WindowManagerImpl.getDefault().dumpGfxInfo(fd);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800940 }
941
942 private void printRow(PrintWriter pw, String format, Object...objs) {
943 pw.println(String.format(format, objs));
944 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800945
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800946 public void setCoreSettings(Bundle coreSettings) {
947 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800948 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400949
950 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) {
951 UpdateCompatibilityData ucd = new UpdateCompatibilityData();
952 ucd.pkg = pkg;
953 ucd.info = info;
954 queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd);
955 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700956
957 public void scheduleTrimMemory(int level) {
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -0700958 queueOrSendMessage(H.TRIM_MEMORY, null, level);
Dianne Hackbornce86ba82011-07-13 19:33:41 -0700959 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 }
961
Romain Guy65b345f2011-07-27 18:51:50 -0700962 private class H extends Handler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 public static final int LAUNCH_ACTIVITY = 100;
964 public static final int PAUSE_ACTIVITY = 101;
965 public static final int PAUSE_ACTIVITY_FINISHING= 102;
966 public static final int STOP_ACTIVITY_SHOW = 103;
967 public static final int STOP_ACTIVITY_HIDE = 104;
968 public static final int SHOW_WINDOW = 105;
969 public static final int HIDE_WINDOW = 106;
970 public static final int RESUME_ACTIVITY = 107;
971 public static final int SEND_RESULT = 108;
Brian Carlstromed7e0072011-03-24 13:27:57 -0700972 public static final int DESTROY_ACTIVITY = 109;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 public static final int BIND_APPLICATION = 110;
974 public static final int EXIT_APPLICATION = 111;
975 public static final int NEW_INTENT = 112;
976 public static final int RECEIVER = 113;
977 public static final int CREATE_SERVICE = 114;
978 public static final int SERVICE_ARGS = 115;
979 public static final int STOP_SERVICE = 116;
980 public static final int REQUEST_THUMBNAIL = 117;
981 public static final int CONFIGURATION_CHANGED = 118;
982 public static final int CLEAN_UP_CONTEXT = 119;
983 public static final int GC_WHEN_IDLE = 120;
984 public static final int BIND_SERVICE = 121;
985 public static final int UNBIND_SERVICE = 122;
986 public static final int DUMP_SERVICE = 123;
987 public static final int LOW_MEMORY = 124;
988 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
989 public static final int RELAUNCH_ACTIVITY = 126;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800990 public static final int PROFILER_CONTROL = 127;
Christopher Tate181fafa2009-05-14 11:12:14 -0700991 public static final int CREATE_BACKUP_AGENT = 128;
Christopher Tate5e1ab332009-09-01 20:32:49 -0700992 public static final int DESTROY_BACKUP_AGENT = 129;
993 public static final int SUICIDE = 130;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700994 public static final int REMOVE_PROVIDER = 131;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -0800995 public static final int ENABLE_JIT = 132;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700996 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700997 public static final int SCHEDULE_CRASH = 134;
Andy McFadden824c5102010-07-09 16:26:57 -0700998 public static final int DUMP_HEAP = 135;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700999 public static final int DUMP_ACTIVITY = 136;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001000 public static final int SLEEPING = 137;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001001 public static final int SET_CORE_SETTINGS = 138;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001002 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001003 public static final int TRIM_MEMORY = 140;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 String codeToString(int code) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001005 if (DEBUG_MESSAGES) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001006 switch (code) {
1007 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
1008 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
1009 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
1010 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
1011 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
1012 case SHOW_WINDOW: return "SHOW_WINDOW";
1013 case HIDE_WINDOW: return "HIDE_WINDOW";
1014 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
1015 case SEND_RESULT: return "SEND_RESULT";
1016 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
1017 case BIND_APPLICATION: return "BIND_APPLICATION";
1018 case EXIT_APPLICATION: return "EXIT_APPLICATION";
1019 case NEW_INTENT: return "NEW_INTENT";
1020 case RECEIVER: return "RECEIVER";
1021 case CREATE_SERVICE: return "CREATE_SERVICE";
1022 case SERVICE_ARGS: return "SERVICE_ARGS";
1023 case STOP_SERVICE: return "STOP_SERVICE";
1024 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
1025 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
1026 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
1027 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
1028 case BIND_SERVICE: return "BIND_SERVICE";
1029 case UNBIND_SERVICE: return "UNBIND_SERVICE";
1030 case DUMP_SERVICE: return "DUMP_SERVICE";
1031 case LOW_MEMORY: return "LOW_MEMORY";
1032 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
1033 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001034 case PROFILER_CONTROL: return "PROFILER_CONTROL";
Christopher Tate181fafa2009-05-14 11:12:14 -07001035 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
1036 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
Christopher Tate5e1ab332009-09-01 20:32:49 -07001037 case SUICIDE: return "SUICIDE";
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001038 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001039 case ENABLE_JIT: return "ENABLE_JIT";
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001040 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001041 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
Andy McFadden824c5102010-07-09 16:26:57 -07001042 case DUMP_HEAP: return "DUMP_HEAP";
Dianne Hackborn625ac272010-09-17 18:29:22 -07001043 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001044 case SLEEPING: return "SLEEPING";
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001045 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001046 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO";
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001047 case TRIM_MEMORY: return "TRIM_MEMORY";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001048 }
1049 }
1050 return "(unknown)";
1051 }
1052 public void handleMessage(Message msg) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001053 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001054 switch (msg.what) {
1055 case LAUNCH_ACTIVITY: {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001056 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001057
1058 r.packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001059 r.activityInfo.applicationInfo, r.compatInfo);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001060 handleLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001061 } break;
1062 case RELAUNCH_ACTIVITY: {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001063 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08001064 handleRelaunchActivity(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 } break;
1066 case PAUSE_ACTIVITY:
1067 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
Bob Leee5408332009-09-04 18:31:17 -07001068 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001069 break;
1070 case PAUSE_ACTIVITY_FINISHING:
1071 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
1072 break;
1073 case STOP_ACTIVITY_SHOW:
1074 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
1075 break;
1076 case STOP_ACTIVITY_HIDE:
1077 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
1078 break;
1079 case SHOW_WINDOW:
1080 handleWindowVisibility((IBinder)msg.obj, true);
1081 break;
1082 case HIDE_WINDOW:
1083 handleWindowVisibility((IBinder)msg.obj, false);
1084 break;
1085 case RESUME_ACTIVITY:
1086 handleResumeActivity((IBinder)msg.obj, true,
1087 msg.arg1 != 0);
1088 break;
1089 case SEND_RESULT:
1090 handleSendResult((ResultData)msg.obj);
1091 break;
1092 case DESTROY_ACTIVITY:
1093 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1094 msg.arg2, false);
1095 break;
1096 case BIND_APPLICATION:
1097 AppBindData data = (AppBindData)msg.obj;
1098 handleBindApplication(data);
1099 break;
1100 case EXIT_APPLICATION:
1101 if (mInitialApplication != null) {
1102 mInitialApplication.onTerminate();
1103 }
1104 Looper.myLooper().quit();
1105 break;
1106 case NEW_INTENT:
1107 handleNewIntent((NewIntentData)msg.obj);
1108 break;
1109 case RECEIVER:
1110 handleReceiver((ReceiverData)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001111 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001112 break;
1113 case CREATE_SERVICE:
1114 handleCreateService((CreateServiceData)msg.obj);
1115 break;
1116 case BIND_SERVICE:
1117 handleBindService((BindServiceData)msg.obj);
1118 break;
1119 case UNBIND_SERVICE:
1120 handleUnbindService((BindServiceData)msg.obj);
1121 break;
1122 case SERVICE_ARGS:
1123 handleServiceArgs((ServiceArgsData)msg.obj);
1124 break;
1125 case STOP_SERVICE:
1126 handleStopService((IBinder)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001127 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001128 break;
1129 case REQUEST_THUMBNAIL:
1130 handleRequestThumbnail((IBinder)msg.obj);
1131 break;
1132 case CONFIGURATION_CHANGED:
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001133 handleConfigurationChanged((Configuration)msg.obj, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 break;
1135 case CLEAN_UP_CONTEXT:
1136 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1137 cci.context.performFinalCleanup(cci.who, cci.what);
1138 break;
1139 case GC_WHEN_IDLE:
1140 scheduleGcIdler();
1141 break;
1142 case DUMP_SERVICE:
Dianne Hackborn625ac272010-09-17 18:29:22 -07001143 handleDumpService((DumpComponentInfo)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 break;
1145 case LOW_MEMORY:
1146 handleLowMemory();
1147 break;
1148 case ACTIVITY_CONFIGURATION_CHANGED:
1149 handleActivityConfigurationChanged((IBinder)msg.obj);
1150 break;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001151 case PROFILER_CONTROL:
Romain Guy7eabe552011-07-21 14:56:34 -07001152 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001153 break;
Christopher Tate181fafa2009-05-14 11:12:14 -07001154 case CREATE_BACKUP_AGENT:
1155 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1156 break;
1157 case DESTROY_BACKUP_AGENT:
1158 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1159 break;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001160 case SUICIDE:
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001161 Process.killProcess(Process.myPid());
1162 break;
1163 case REMOVE_PROVIDER:
1164 completeRemoveProvider((IContentProvider)msg.obj);
Christopher Tate5e1ab332009-09-01 20:32:49 -07001165 break;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001166 case ENABLE_JIT:
1167 ensureJitEnabled();
1168 break;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001169 case DISPATCH_PACKAGE_BROADCAST:
1170 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1171 break;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001172 case SCHEDULE_CRASH:
1173 throw new RemoteServiceException((String)msg.obj);
Andy McFadden824c5102010-07-09 16:26:57 -07001174 case DUMP_HEAP:
1175 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1176 break;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001177 case DUMP_ACTIVITY:
1178 handleDumpActivity((DumpComponentInfo)msg.obj);
1179 break;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001180 case SLEEPING:
1181 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1182 break;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001183 case SET_CORE_SETTINGS:
1184 handleSetCoreSettings((Bundle) msg.obj);
1185 break;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001186 case UPDATE_PACKAGE_COMPATIBILITY_INFO:
1187 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001188 break;
Dianne Hackbornce86ba82011-07-13 19:33:41 -07001189 case TRIM_MEMORY:
1190 handleTrimMemory(msg.arg1);
Dianne Hackbornf0754f5b2011-07-21 16:02:07 -07001191 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07001193 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 }
Bob Leee5408332009-09-04 18:31:17 -07001195
Brian Carlstromed7e0072011-03-24 13:27:57 -07001196 private void maybeSnapshot() {
1197 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
Sen Hubde75702010-05-28 01:54:03 -07001198 // convert the *private* ActivityThread.PackageInfo to *public* known
1199 // android.content.pm.PackageInfo
1200 String packageName = mBoundApplication.info.mPackageName;
1201 android.content.pm.PackageInfo packageInfo = null;
1202 try {
1203 Context context = getSystemContext();
1204 if(context == null) {
1205 Log.e(TAG, "cannot get a valid context");
1206 return;
1207 }
1208 PackageManager pm = context.getPackageManager();
1209 if(pm == null) {
1210 Log.e(TAG, "cannot get a valid PackageManager");
1211 return;
1212 }
1213 packageInfo = pm.getPackageInfo(
1214 packageName, PackageManager.GET_ACTIVITIES);
1215 } catch (NameNotFoundException e) {
1216 Log.e(TAG, "cannot get package info for " + packageName, e);
1217 }
1218 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
Bob Leee5408332009-09-04 18:31:17 -07001219 }
1220 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221 }
1222
Romain Guy65b345f2011-07-27 18:51:50 -07001223 private class Idler implements MessageQueue.IdleHandler {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224 public final boolean queueIdle() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001225 ActivityClientRecord a = mNewActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001226 if (a != null) {
1227 mNewActivities = null;
1228 IActivityManager am = ActivityManagerNative.getDefault();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001229 ActivityClientRecord prev;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 do {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001231 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232 TAG, "Reporting idle of " + a +
1233 " finished=" +
Romain Guy65b345f2011-07-27 18:51:50 -07001234 (a.activity != null && a.activity.mFinished));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 if (a.activity != null && !a.activity.mFinished) {
1236 try {
Dianne Hackborne88846e2009-09-30 21:34:25 -07001237 am.activityIdle(a.token, a.createdConfig);
1238 a.createdConfig = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07001240 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 }
1242 }
1243 prev = a;
1244 a = a.nextIdle;
1245 prev.nextIdle = null;
1246 } while (a != null);
1247 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001248 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 return false;
1250 }
1251 }
1252
1253 final class GcIdler implements MessageQueue.IdleHandler {
1254 public final boolean queueIdle() {
1255 doGcIfNeeded();
1256 return false;
1257 }
1258 }
1259
Romain Guy65b345f2011-07-27 18:51:50 -07001260 private static class ResourcesKey {
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001261 final private String mResDir;
1262 final private float mScale;
1263 final private int mHash;
Bob Leee5408332009-09-04 18:31:17 -07001264
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001265 ResourcesKey(String resDir, float scale) {
1266 mResDir = resDir;
1267 mScale = scale;
1268 mHash = mResDir.hashCode() << 2 + (int) (mScale * 2);
1269 }
Bob Leee5408332009-09-04 18:31:17 -07001270
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001271 @Override
1272 public int hashCode() {
1273 return mHash;
1274 }
1275
1276 @Override
1277 public boolean equals(Object obj) {
1278 if (!(obj instanceof ResourcesKey)) {
1279 return false;
1280 }
1281 ResourcesKey peer = (ResourcesKey) obj;
1282 return mResDir.equals(peer.mResDir) && mScale == peer.mScale;
1283 }
1284 }
1285
Romain Guy65b345f2011-07-27 18:51:50 -07001286 public static ActivityThread currentActivityThread() {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07001287 return sThreadLocal.get();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289
Romain Guy65b345f2011-07-27 18:51:50 -07001290 public static String currentPackageName() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001291 ActivityThread am = currentActivityThread();
1292 return (am != null && am.mBoundApplication != null)
1293 ? am.mBoundApplication.processName : null;
1294 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295
Romain Guy65b345f2011-07-27 18:51:50 -07001296 public static Application currentApplication() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001297 ActivityThread am = currentActivityThread();
1298 return am != null ? am.mInitialApplication : null;
1299 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001301 public static IPackageManager getPackageManager() {
1302 if (sPackageManager != null) {
1303 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1304 return sPackageManager;
1305 }
1306 IBinder b = ServiceManager.getService("package");
1307 //Slog.v("PackageManager", "default service binder = " + b);
1308 sPackageManager = IPackageManager.Stub.asInterface(b);
1309 //Slog.v("PackageManager", "default service = " + sPackageManager);
1310 return sPackageManager;
1311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001313 DisplayMetrics getDisplayMetricsLocked(CompatibilityInfo ci, boolean forceUpdate) {
1314 DisplayMetrics dm = mDisplayMetrics.get(ci);
1315 if (dm != null && !forceUpdate) {
1316 return dm;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001317 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001318 if (dm == null) {
1319 dm = new DisplayMetrics();
1320 mDisplayMetrics.put(ci, dm);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001321 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001322 Display d = WindowManagerImpl.getDefault(ci).getDefaultDisplay();
1323 d.getMetrics(dm);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001324 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1325 // + metrics.heightPixels + " den=" + metrics.density
1326 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001327 return dm;
1328 }
1329
1330 static Configuration applyConfigCompat(Configuration config, CompatibilityInfo compat) {
1331 if (config == null) {
1332 return null;
1333 }
1334 if (compat != null && !compat.supportsScreen()) {
1335 config = new Configuration(config);
1336 compat.applyToConfiguration(config);
1337 }
1338 return config;
1339 }
1340
Romain Guy65b345f2011-07-27 18:51:50 -07001341 private Configuration mMainThreadConfig = new Configuration();
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001342 Configuration applyConfigCompatMainThread(Configuration config, CompatibilityInfo compat) {
1343 if (config == null) {
1344 return null;
1345 }
1346 if (compat != null && !compat.supportsScreen()) {
1347 mMainThreadConfig.setTo(config);
1348 config = mMainThreadConfig;
1349 compat.applyToConfiguration(config);
1350 }
1351 return config;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001352 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001354 /**
1355 * Creates the top level Resources for applications with the given compatibility info.
1356 *
1357 * @param resDir the resource directory.
1358 * @param compInfo the compability info. It will use the default compatibility info when it's
1359 * null.
1360 */
1361 Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
1362 ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
1363 Resources r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001365 // Resources is app scale dependent.
1366 if (false) {
1367 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1368 + compInfo.applicationScale);
1369 }
1370 WeakReference<Resources> wr = mActiveResources.get(key);
1371 r = wr != null ? wr.get() : null;
1372 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1373 if (r != null && r.getAssets().isUpToDate()) {
1374 if (false) {
1375 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1376 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1377 }
1378 return r;
1379 }
1380 }
1381
1382 //if (r != null) {
1383 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1384 // + r + " " + resDir);
1385 //}
1386
1387 AssetManager assets = new AssetManager();
1388 if (assets.addAssetPath(resDir) == 0) {
1389 return null;
1390 }
1391
1392 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001393 DisplayMetrics metrics = getDisplayMetricsLocked(compInfo, false);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001394 r = new Resources(assets, metrics, getConfiguration(), compInfo);
1395 if (false) {
1396 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1397 + r.getConfiguration() + " appScale="
1398 + r.getCompatibilityInfo().applicationScale);
1399 }
1400
1401 synchronized (mPackages) {
1402 WeakReference<Resources> wr = mActiveResources.get(key);
1403 Resources existing = wr != null ? wr.get() : null;
1404 if (existing != null && existing.getAssets().isUpToDate()) {
1405 // Someone else already created the resources while we were
1406 // unlocked; go ahead and use theirs.
1407 r.getAssets().close();
1408 return existing;
1409 }
1410
1411 // XXX need to remove entries when weak references go away
1412 mActiveResources.put(key, new WeakReference<Resources>(r));
1413 return r;
1414 }
1415 }
1416
1417 /**
1418 * Creates the top level resources for the given package.
1419 */
1420 Resources getTopLevelResources(String resDir, LoadedApk pkgInfo) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001421 return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo.get());
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001422 }
1423
1424 final Handler getHandler() {
1425 return mH;
1426 }
1427
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001428 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo,
1429 int flags) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001430 synchronized (mPackages) {
1431 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1433 ref = mPackages.get(packageName);
1434 } else {
1435 ref = mResourcePackages.get(packageName);
1436 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001437 LoadedApk packageInfo = ref != null ? ref.get() : null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001438 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001439 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1440 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 if (packageInfo != null && (packageInfo.mResources == null
1442 || packageInfo.mResources.getAssets().isUpToDate())) {
1443 if (packageInfo.isSecurityViolation()
1444 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1445 throw new SecurityException(
1446 "Requesting code from " + packageName
1447 + " to be run in process "
1448 + mBoundApplication.processName
1449 + "/" + mBoundApplication.appInfo.uid);
1450 }
1451 return packageInfo;
1452 }
1453 }
1454
1455 ApplicationInfo ai = null;
1456 try {
1457 ai = getPackageManager().getApplicationInfo(packageName,
1458 PackageManager.GET_SHARED_LIBRARY_FILES);
1459 } catch (RemoteException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07001460 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001461 }
1462
1463 if (ai != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001464 return getPackageInfo(ai, compatInfo, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001465 }
1466
1467 return null;
1468 }
1469
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001470 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo,
1471 int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001472 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1473 boolean securityViolation = includeCode && ai.uid != 0
1474 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1475 ? ai.uid != mBoundApplication.appInfo.uid : true);
1476 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1477 |Context.CONTEXT_IGNORE_SECURITY))
1478 == Context.CONTEXT_INCLUDE_CODE) {
1479 if (securityViolation) {
1480 String msg = "Requesting code from " + ai.packageName
1481 + " (with uid " + ai.uid + ")";
1482 if (mBoundApplication != null) {
1483 msg = msg + " to be run in process "
1484 + mBoundApplication.processName + " (with uid "
1485 + mBoundApplication.appInfo.uid + ")";
1486 }
1487 throw new SecurityException(msg);
1488 }
1489 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001490 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001491 }
1492
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001493 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
1494 CompatibilityInfo compatInfo) {
1495 return getPackageInfo(ai, compatInfo, null, false, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001496 }
1497
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001498 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) {
1499 synchronized (mPackages) {
1500 WeakReference<LoadedApk> ref;
1501 if (includeCode) {
1502 ref = mPackages.get(packageName);
1503 } else {
1504 ref = mResourcePackages.get(packageName);
1505 }
1506 return ref != null ? ref.get() : null;
1507 }
1508 }
1509
Romain Guy65b345f2011-07-27 18:51:50 -07001510 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1512 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001513 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 if (includeCode) {
1515 ref = mPackages.get(aInfo.packageName);
1516 } else {
1517 ref = mResourcePackages.get(aInfo.packageName);
1518 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001519 LoadedApk packageInfo = ref != null ? ref.get() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001520 if (packageInfo == null || (packageInfo.mResources != null
1521 && !packageInfo.mResources.getAssets().isUpToDate())) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001522 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 : "Loading resource-only package ") + aInfo.packageName
1524 + " (in " + (mBoundApplication != null
1525 ? mBoundApplication.processName : null)
1526 + ")");
1527 packageInfo =
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001528 new LoadedApk(this, aInfo, compatInfo, this, baseLoader,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 securityViolation, includeCode &&
1530 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1531 if (includeCode) {
1532 mPackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001533 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 } else {
1535 mResourcePackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001536 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 }
1538 }
1539 return packageInfo;
1540 }
1541 }
1542
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001543 ActivityThread() {
1544 }
1545
1546 public ApplicationThread getApplicationThread()
1547 {
1548 return mAppThread;
1549 }
1550
1551 public Instrumentation getInstrumentation()
1552 {
1553 return mInstrumentation;
1554 }
1555
1556 public Configuration getConfiguration() {
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001557 return mResConfiguration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 }
1559
1560 public boolean isProfiling() {
1561 return mBoundApplication != null && mBoundApplication.profileFile != null;
1562 }
1563
1564 public String getProfileFilePath() {
1565 return mBoundApplication.profileFile;
1566 }
1567
1568 public Looper getLooper() {
1569 return mLooper;
1570 }
1571
1572 public Application getApplication() {
1573 return mInitialApplication;
1574 }
Bob Leee5408332009-09-04 18:31:17 -07001575
Dianne Hackbornd97c7ad2009-06-19 11:37:35 -07001576 public String getProcessName() {
1577 return mBoundApplication.processName;
1578 }
Bob Leee5408332009-09-04 18:31:17 -07001579
Dianne Hackborn21556372010-02-04 16:34:40 -08001580 public ContextImpl getSystemContext() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 synchronized (this) {
1582 if (mSystemContext == null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001583 ContextImpl context =
1584 ContextImpl.createSystemContext(this);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001585 LoadedApk info = new LoadedApk(this, "android", context, null,
1586 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 context.init(info, null, this);
1588 context.getResources().updateConfiguration(
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001589 getConfiguration(), getDisplayMetricsLocked(
1590 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, false));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001591 mSystemContext = context;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001592 //Slog.i(TAG, "Created system resources " + context.getResources()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 // + ": " + context.getResources().getConfiguration());
1594 }
1595 }
1596 return mSystemContext;
1597 }
1598
Mike Cleron432b7132009-09-24 15:28:29 -07001599 public void installSystemApplicationInfo(ApplicationInfo info) {
1600 synchronized (this) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001601 ContextImpl context = getSystemContext();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001602 context.init(new LoadedApk(this, "android", context, info,
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07001603 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this);
Mike Cleron432b7132009-09-24 15:28:29 -07001604 }
1605 }
1606
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001607 void ensureJitEnabled() {
1608 if (!mJitEnabled) {
1609 mJitEnabled = true;
1610 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1611 }
1612 }
1613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 void scheduleGcIdler() {
1615 if (!mGcIdlerScheduled) {
1616 mGcIdlerScheduled = true;
1617 Looper.myQueue().addIdleHandler(mGcIdler);
1618 }
1619 mH.removeMessages(H.GC_WHEN_IDLE);
1620 }
1621
1622 void unscheduleGcIdler() {
1623 if (mGcIdlerScheduled) {
1624 mGcIdlerScheduled = false;
1625 Looper.myQueue().removeIdleHandler(mGcIdler);
1626 }
1627 mH.removeMessages(H.GC_WHEN_IDLE);
1628 }
1629
1630 void doGcIfNeeded() {
1631 mGcIdlerScheduled = false;
1632 final long now = SystemClock.uptimeMillis();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001633 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001634 // + "m now=" + now);
1635 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001636 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 BinderInternal.forceGc("bg");
1638 }
1639 }
1640
Jeff Hamilton52d32032011-01-08 15:31:26 -06001641 public void registerOnActivityPausedListener(Activity activity,
1642 OnActivityPausedListener listener) {
1643 synchronized (mOnPauseListeners) {
1644 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1645 if (list == null) {
1646 list = new ArrayList<OnActivityPausedListener>();
1647 mOnPauseListeners.put(activity, list);
1648 }
1649 list.add(listener);
1650 }
1651 }
1652
Jeff Hamiltonce3224c2011-01-17 11:05:03 -08001653 public void unregisterOnActivityPausedListener(Activity activity,
1654 OnActivityPausedListener listener) {
1655 synchronized (mOnPauseListeners) {
1656 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1657 if (list != null) {
1658 list.remove(listener);
1659 }
1660 }
1661 }
1662
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001663 public final ActivityInfo resolveActivityInfo(Intent intent) {
1664 ActivityInfo aInfo = intent.resolveActivityInfo(
1665 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
1666 if (aInfo == null) {
1667 // Throw an exception.
1668 Instrumentation.checkStartActivityResult(
1669 IActivityManager.START_CLASS_NOT_FOUND, intent);
1670 }
1671 return aInfo;
1672 }
Bob Leee5408332009-09-04 18:31:17 -07001673
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001674 public final Activity startActivityNow(Activity parent, String id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001676 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001677 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001679 r.ident = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 r.intent = intent;
1681 r.state = state;
1682 r.parent = parent;
1683 r.embeddedID = id;
1684 r.activityInfo = activityInfo;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001685 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001686 if (localLOGV) {
1687 ComponentName compname = intent.getComponent();
1688 String name;
1689 if (compname != null) {
1690 name = compname.toShortString();
1691 } else {
1692 name = "(Intent " + intent + ").getComponent() returned null";
1693 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001694 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001695 + ", comp=" + name
1696 + ", token=" + token);
1697 }
Christopher Tateb70f3df2009-04-07 16:07:59 -07001698 return performLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 }
1700
1701 public final Activity getActivity(IBinder token) {
1702 return mActivities.get(token).activity;
1703 }
1704
1705 public final void sendActivityResult(
1706 IBinder token, String id, int requestCode,
1707 int resultCode, Intent data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001708 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
Chris Tate8a7dc172009-03-24 20:11:42 -07001709 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
1711 list.add(new ResultInfo(id, requestCode, resultCode, data));
1712 mAppThread.scheduleSendResult(token, list);
1713 }
1714
1715 // if the thread hasn't started yet, we don't have the handler, so just
1716 // save the messages until we're ready.
Romain Guy65b345f2011-07-27 18:51:50 -07001717 private void queueOrSendMessage(int what, Object obj) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001718 queueOrSendMessage(what, obj, 0, 0);
1719 }
1720
Romain Guy65b345f2011-07-27 18:51:50 -07001721 private void queueOrSendMessage(int what, Object obj, int arg1) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722 queueOrSendMessage(what, obj, arg1, 0);
1723 }
1724
Romain Guy65b345f2011-07-27 18:51:50 -07001725 private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001726 synchronized (this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001727 if (DEBUG_MESSAGES) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001728 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
1729 + ": " + arg1 + " / " + obj);
1730 Message msg = Message.obtain();
1731 msg.what = what;
1732 msg.obj = obj;
1733 msg.arg1 = arg1;
1734 msg.arg2 = arg2;
1735 mH.sendMessage(msg);
1736 }
1737 }
1738
Dianne Hackborn21556372010-02-04 16:34:40 -08001739 final void scheduleContextCleanup(ContextImpl context, String who,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001740 String what) {
1741 ContextCleanupInfo cci = new ContextCleanupInfo();
1742 cci.context = context;
1743 cci.who = who;
1744 cci.what = what;
1745 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
1746 }
1747
Romain Guy65b345f2011-07-27 18:51:50 -07001748 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001749 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
1750
1751 ActivityInfo aInfo = r.activityInfo;
1752 if (r.packageInfo == null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001753 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754 Context.CONTEXT_INCLUDE_CODE);
1755 }
Bob Leee5408332009-09-04 18:31:17 -07001756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001757 ComponentName component = r.intent.getComponent();
1758 if (component == null) {
1759 component = r.intent.resolveActivity(
1760 mInitialApplication.getPackageManager());
1761 r.intent.setComponent(component);
1762 }
1763
1764 if (r.activityInfo.targetActivity != null) {
1765 component = new ComponentName(r.activityInfo.packageName,
1766 r.activityInfo.targetActivity);
1767 }
1768
1769 Activity activity = null;
1770 try {
1771 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
1772 activity = mInstrumentation.newActivity(
1773 cl, component.getClassName(), r.intent);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08001774 StrictMode.incrementExpectedActivityCount(activity.getClass());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001775 r.intent.setExtrasClassLoader(cl);
1776 if (r.state != null) {
1777 r.state.setClassLoader(cl);
1778 }
1779 } catch (Exception e) {
1780 if (!mInstrumentation.onException(activity, e)) {
1781 throw new RuntimeException(
1782 "Unable to instantiate activity " + component
1783 + ": " + e.toString(), e);
1784 }
1785 }
1786
1787 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08001788 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07001789
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001790 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
1791 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001792 TAG, r + ": app=" + app
1793 + ", appName=" + app.getPackageName()
1794 + ", pkg=" + r.packageInfo.getPackageName()
1795 + ", comp=" + r.intent.getComponent().toShortString()
1796 + ", dir=" + r.packageInfo.getAppDir());
1797
1798 if (activity != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001799 ContextImpl appContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 appContext.init(r.packageInfo, r.token, this);
1801 appContext.setOuterContext(activity);
1802 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
Dianne Hackborn5fd21692011-06-07 14:09:47 -07001803 Configuration config = new Configuration(mCompatConfiguration);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001804 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07001805 + r.activityInfo.name + " with config " + config);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001806 activity.attach(appContext, this, getInstrumentation(), r.token,
1807 r.ident, app, r.intent, r.activityInfo, title, r.parent,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001808 r.embeddedID, r.lastNonConfigurationInstances, config);
Bob Leee5408332009-09-04 18:31:17 -07001809
Christopher Tateb70f3df2009-04-07 16:07:59 -07001810 if (customIntent != null) {
1811 activity.mIntent = customIntent;
1812 }
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001813 r.lastNonConfigurationInstances = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001814 activity.mStartedActivity = false;
1815 int theme = r.activityInfo.getThemeResource();
1816 if (theme != 0) {
1817 activity.setTheme(theme);
1818 }
1819
1820 activity.mCalled = false;
1821 mInstrumentation.callActivityOnCreate(activity, r.state);
1822 if (!activity.mCalled) {
1823 throw new SuperNotCalledException(
1824 "Activity " + r.intent.getComponent().toShortString() +
1825 " did not call through to super.onCreate()");
1826 }
1827 r.activity = activity;
1828 r.stopped = true;
1829 if (!r.activity.mFinished) {
1830 activity.performStart();
1831 r.stopped = false;
1832 }
1833 if (!r.activity.mFinished) {
1834 if (r.state != null) {
1835 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
1836 }
1837 }
1838 if (!r.activity.mFinished) {
1839 activity.mCalled = false;
1840 mInstrumentation.callActivityOnPostCreate(activity, r.state);
1841 if (!activity.mCalled) {
1842 throw new SuperNotCalledException(
1843 "Activity " + r.intent.getComponent().toShortString() +
1844 " did not call through to super.onPostCreate()");
1845 }
1846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001847 }
1848 r.paused = true;
1849
1850 mActivities.put(r.token, r);
1851
1852 } catch (SuperNotCalledException e) {
1853 throw e;
1854
1855 } catch (Exception e) {
1856 if (!mInstrumentation.onException(activity, e)) {
1857 throw new RuntimeException(
1858 "Unable to start activity " + component
1859 + ": " + e.toString(), e);
1860 }
1861 }
1862
1863 return activity;
1864 }
1865
Romain Guy65b345f2011-07-27 18:51:50 -07001866 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001867 // If we are getting ready to gc after going to the background, well
1868 // we are back active so skip it.
1869 unscheduleGcIdler();
1870
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001871 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001872 TAG, "Handling launch of " + r);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001873 Activity a = performLaunchActivity(r, customIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001874
1875 if (a != null) {
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08001876 r.createdConfig = new Configuration(mConfiguration);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001877 Bundle oldState = r.state;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001878 handleResumeActivity(r.token, false, r.isForward);
1879
1880 if (!r.activity.mFinished && r.startsNotResumed) {
1881 // The activity manager actually wants this one to start out
1882 // paused, because it needs to be visible but isn't in the
1883 // foreground. We accomplish this by going through the
1884 // normal startup (because activities expect to go through
1885 // onResume() the first time they run, before their window
1886 // is displayed), and then pausing it. However, in this case
1887 // we do -not- need to do the full pause cycle (of freezing
1888 // and such) because the activity manager assumes it can just
1889 // retain the current state it has.
1890 try {
1891 r.activity.mCalled = false;
1892 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001893 // We need to keep around the original state, in case
1894 // we need to be created again.
1895 r.state = oldState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001896 if (!r.activity.mCalled) {
1897 throw new SuperNotCalledException(
1898 "Activity " + r.intent.getComponent().toShortString() +
1899 " did not call through to super.onPause()");
1900 }
1901
1902 } catch (SuperNotCalledException e) {
1903 throw e;
1904
1905 } catch (Exception e) {
1906 if (!mInstrumentation.onException(r.activity, e)) {
1907 throw new RuntimeException(
1908 "Unable to pause activity "
1909 + r.intent.getComponent().toShortString()
1910 + ": " + e.toString(), e);
1911 }
1912 }
1913 r.paused = true;
1914 }
1915 } else {
1916 // If there was an error, for any reason, tell the activity
1917 // manager to stop us.
1918 try {
1919 ActivityManagerNative.getDefault()
1920 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
1921 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07001922 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001923 }
1924 }
1925 }
1926
Romain Guy65b345f2011-07-27 18:51:50 -07001927 private void deliverNewIntents(ActivityClientRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001928 List<Intent> intents) {
1929 final int N = intents.size();
1930 for (int i=0; i<N; i++) {
1931 Intent intent = intents.get(i);
1932 intent.setExtrasClassLoader(r.activity.getClassLoader());
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07001933 r.activity.mFragments.noteStateNotSaved();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001934 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
1935 }
1936 }
1937
1938 public final void performNewIntents(IBinder token,
1939 List<Intent> intents) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001940 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001941 if (r != null) {
1942 final boolean resumed = !r.paused;
1943 if (resumed) {
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07001944 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001945 mInstrumentation.callActivityOnPause(r.activity);
1946 }
1947 deliverNewIntents(r, intents);
1948 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07001949 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07001950 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001951 }
1952 }
1953 }
Bob Leee5408332009-09-04 18:31:17 -07001954
Romain Guy65b345f2011-07-27 18:51:50 -07001955 private void handleNewIntent(NewIntentData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001956 performNewIntents(data.token, data.intents);
1957 }
1958
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07001959 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
1960
1961 /**
1962 * Return the Intent that's currently being handled by a
1963 * BroadcastReceiver on this thread, or null if none.
1964 * @hide
1965 */
1966 public static Intent getIntentBeingBroadcast() {
1967 return sCurrentBroadcastIntent.get();
1968 }
1969
Romain Guy65b345f2011-07-27 18:51:50 -07001970 private void handleReceiver(ReceiverData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001971 // If we are getting ready to gc after going to the background, well
1972 // we are back active so skip it.
1973 unscheduleGcIdler();
1974
1975 String component = data.intent.getComponent().getClassName();
1976
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001977 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001978 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001979
1980 IActivityManager mgr = ActivityManagerNative.getDefault();
1981
Romain Guy65b345f2011-07-27 18:51:50 -07001982 BroadcastReceiver receiver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001983 try {
1984 java.lang.ClassLoader cl = packageInfo.getClassLoader();
1985 data.intent.setExtrasClassLoader(cl);
Dianne Hackborne829fef2010-10-26 17:44:01 -07001986 data.setExtrasClassLoader(cl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001987 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
1988 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001989 if (DEBUG_BROADCAST) Slog.i(TAG,
1990 "Finishing failed broadcast to " + data.intent.getComponent());
1991 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001992 throw new RuntimeException(
1993 "Unable to instantiate receiver " + component
1994 + ": " + e.toString(), e);
1995 }
1996
1997 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08001998 Application app = packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07001999
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002000 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002001 TAG, "Performing receive of " + data.intent
2002 + ": app=" + app
2003 + ", appName=" + app.getPackageName()
2004 + ", pkg=" + packageInfo.getPackageName()
2005 + ", comp=" + data.intent.getComponent().toShortString()
2006 + ", dir=" + packageInfo.getAppDir());
2007
Dianne Hackborn21556372010-02-04 16:34:40 -08002008 ContextImpl context = (ContextImpl)app.getBaseContext();
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002009 sCurrentBroadcastIntent.set(data.intent);
Dianne Hackborne829fef2010-10-26 17:44:01 -07002010 receiver.setPendingResult(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002011 receiver.onReceive(context.getReceiverRestrictedContext(),
2012 data.intent);
2013 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07002014 if (DEBUG_BROADCAST) Slog.i(TAG,
2015 "Finishing failed broadcast to " + data.intent.getComponent());
2016 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 if (!mInstrumentation.onException(receiver, e)) {
2018 throw new RuntimeException(
2019 "Unable to start receiver " + component
2020 + ": " + e.toString(), e);
2021 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07002022 } finally {
2023 sCurrentBroadcastIntent.set(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002024 }
2025
Dianne Hackborne829fef2010-10-26 17:44:01 -07002026 if (receiver.getPendingResult() != null) {
2027 data.finish();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002028 }
2029 }
2030
Christopher Tate181fafa2009-05-14 11:12:14 -07002031 // Instantiate a BackupAgent and tell it that it's alive
Romain Guy65b345f2011-07-27 18:51:50 -07002032 private void handleCreateBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002033 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002034
2035 // no longer idle; we have backup work to do
2036 unscheduleGcIdler();
2037
2038 // instantiate the BackupAgent class named in the manifest
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002039 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002040 String packageName = packageInfo.mPackageName;
2041 if (mBackupAgents.get(packageName) != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002042 Slog.d(TAG, "BackupAgent " + " for " + packageName
Christopher Tate181fafa2009-05-14 11:12:14 -07002043 + " already exists");
2044 return;
2045 }
Bob Leee5408332009-09-04 18:31:17 -07002046
Christopher Tate181fafa2009-05-14 11:12:14 -07002047 BackupAgent agent = null;
2048 String classname = data.appInfo.backupAgentName;
Christopher Tate4a627c72011-04-01 14:43:32 -07002049
Christopher Tate79ec80d2011-06-24 14:58:49 -07002050 // full backup operation but no app-supplied agent? use the default implementation
2051 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL
2052 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) {
Christopher Tate4a627c72011-04-01 14:43:32 -07002053 classname = "android.app.backup.FullBackupAgent";
Christopher Tate181fafa2009-05-14 11:12:14 -07002054 }
Christopher Tate4a627c72011-04-01 14:43:32 -07002055
Christopher Tate181fafa2009-05-14 11:12:14 -07002056 try {
Christopher Tated1475e02009-07-09 15:36:17 -07002057 IBinder binder = null;
2058 try {
Christopher Tate4a627c72011-04-01 14:43:32 -07002059 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname);
2060
Christopher Tated1475e02009-07-09 15:36:17 -07002061 java.lang.ClassLoader cl = packageInfo.getClassLoader();
Christopher Tate4a627c72011-04-01 14:43:32 -07002062 agent = (BackupAgent) cl.loadClass(classname).newInstance();
Christopher Tated1475e02009-07-09 15:36:17 -07002063
2064 // set up the agent's context
Dianne Hackborn21556372010-02-04 16:34:40 -08002065 ContextImpl context = new ContextImpl();
Christopher Tated1475e02009-07-09 15:36:17 -07002066 context.init(packageInfo, null, this);
2067 context.setOuterContext(agent);
2068 agent.attach(context);
2069
2070 agent.onCreate();
2071 binder = agent.onBind();
2072 mBackupAgents.put(packageName, agent);
2073 } catch (Exception e) {
2074 // If this is during restore, fail silently; otherwise go
2075 // ahead and let the user see the crash.
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002076 Slog.e(TAG, "Agent threw during creation: " + e);
Christopher Tate75a99702011-05-18 16:28:19 -07002077 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE
2078 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) {
Christopher Tated1475e02009-07-09 15:36:17 -07002079 throw e;
2080 }
2081 // falling through with 'binder' still null
2082 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002083
2084 // tell the OS that we're live now
Christopher Tate181fafa2009-05-14 11:12:14 -07002085 try {
2086 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
2087 } catch (RemoteException e) {
2088 // nothing to do.
2089 }
Christopher Tate181fafa2009-05-14 11:12:14 -07002090 } catch (Exception e) {
2091 throw new RuntimeException("Unable to create BackupAgent "
Christopher Tate4a627c72011-04-01 14:43:32 -07002092 + classname + ": " + e.toString(), e);
Christopher Tate181fafa2009-05-14 11:12:14 -07002093 }
2094 }
2095
2096 // Tear down a BackupAgent
Romain Guy65b345f2011-07-27 18:51:50 -07002097 private void handleDestroyBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002098 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
Bob Leee5408332009-09-04 18:31:17 -07002099
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002100 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002101 String packageName = packageInfo.mPackageName;
2102 BackupAgent agent = mBackupAgents.get(packageName);
2103 if (agent != null) {
2104 try {
2105 agent.onDestroy();
2106 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002107 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002108 e.printStackTrace();
2109 }
2110 mBackupAgents.remove(packageName);
2111 } else {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002112 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002113 }
2114 }
2115
Romain Guy65b345f2011-07-27 18:51:50 -07002116 private void handleCreateService(CreateServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 // If we are getting ready to gc after going to the background, well
2118 // we are back active so skip it.
2119 unscheduleGcIdler();
2120
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002121 LoadedApk packageInfo = getPackageInfoNoCheck(
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002122 data.info.applicationInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002123 Service service = null;
2124 try {
2125 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2126 service = (Service) cl.loadClass(data.info.name).newInstance();
2127 } catch (Exception e) {
2128 if (!mInstrumentation.onException(service, e)) {
2129 throw new RuntimeException(
2130 "Unable to instantiate service " + data.info.name
2131 + ": " + e.toString(), e);
2132 }
2133 }
2134
2135 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002136 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137
Dianne Hackborn21556372010-02-04 16:34:40 -08002138 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002139 context.init(packageInfo, null, this);
2140
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002141 Application app = packageInfo.makeApplication(false, mInstrumentation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002142 context.setOuterContext(service);
2143 service.attach(context, this, data.info.name, data.token, app,
2144 ActivityManagerNative.getDefault());
2145 service.onCreate();
2146 mServices.put(data.token, service);
2147 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002148 ActivityManagerNative.getDefault().serviceDoneExecuting(
2149 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 } catch (RemoteException e) {
2151 // nothing to do.
2152 }
2153 } catch (Exception e) {
2154 if (!mInstrumentation.onException(service, e)) {
2155 throw new RuntimeException(
2156 "Unable to create service " + data.info.name
2157 + ": " + e.toString(), e);
2158 }
2159 }
2160 }
2161
Romain Guy65b345f2011-07-27 18:51:50 -07002162 private void handleBindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163 Service s = mServices.get(data.token);
2164 if (s != null) {
2165 try {
2166 data.intent.setExtrasClassLoader(s.getClassLoader());
2167 try {
2168 if (!data.rebind) {
2169 IBinder binder = s.onBind(data.intent);
2170 ActivityManagerNative.getDefault().publishService(
2171 data.token, data.intent, binder);
2172 } else {
2173 s.onRebind(data.intent);
2174 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002175 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002176 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002177 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002178 } catch (RemoteException ex) {
2179 }
2180 } catch (Exception e) {
2181 if (!mInstrumentation.onException(s, e)) {
2182 throw new RuntimeException(
2183 "Unable to bind to service " + s
2184 + " with " + data.intent + ": " + e.toString(), e);
2185 }
2186 }
2187 }
2188 }
2189
Romain Guy65b345f2011-07-27 18:51:50 -07002190 private void handleUnbindService(BindServiceData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002191 Service s = mServices.get(data.token);
2192 if (s != null) {
2193 try {
2194 data.intent.setExtrasClassLoader(s.getClassLoader());
2195 boolean doRebind = s.onUnbind(data.intent);
2196 try {
2197 if (doRebind) {
2198 ActivityManagerNative.getDefault().unbindFinished(
2199 data.token, data.intent, doRebind);
2200 } else {
2201 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002202 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203 }
2204 } catch (RemoteException ex) {
2205 }
2206 } catch (Exception e) {
2207 if (!mInstrumentation.onException(s, e)) {
2208 throw new RuntimeException(
2209 "Unable to unbind to service " + s
2210 + " with " + data.intent + ": " + e.toString(), e);
2211 }
2212 }
2213 }
2214 }
2215
Dianne Hackborn625ac272010-09-17 18:29:22 -07002216 private void handleDumpService(DumpComponentInfo info) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07002217 Service s = mServices.get(info.token);
2218 if (s != null) {
2219 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2220 s.dump(info.fd.getFileDescriptor(), pw, info.args);
2221 pw.flush();
2222 try {
2223 info.fd.close();
2224 } catch (IOException e) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002225 }
2226 }
2227 }
2228
Dianne Hackborn625ac272010-09-17 18:29:22 -07002229 private void handleDumpActivity(DumpComponentInfo info) {
Dianne Hackborne17aeb32011-04-07 15:11:57 -07002230 ActivityClientRecord r = mActivities.get(info.token);
2231 if (r != null && r.activity != null) {
2232 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor()));
2233 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args);
2234 pw.flush();
2235 try {
2236 info.fd.close();
2237 } catch (IOException e) {
Dianne Hackborn625ac272010-09-17 18:29:22 -07002238 }
2239 }
2240 }
2241
Romain Guy65b345f2011-07-27 18:51:50 -07002242 private void handleServiceArgs(ServiceArgsData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002243 Service s = mServices.get(data.token);
2244 if (s != null) {
2245 try {
2246 if (data.args != null) {
2247 data.args.setExtrasClassLoader(s.getClassLoader());
2248 }
Dianne Hackborn0c5001d2011-04-12 18:16:08 -07002249 int res;
2250 if (!data.taskRemoved) {
2251 res = s.onStartCommand(data.args, data.flags, data.startId);
2252 } else {
2253 s.onTaskRemoved(data.args);
2254 res = Service.START_TASK_REMOVED_COMPLETE;
2255 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002256
2257 QueuedWork.waitToFinish();
2258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002260 ActivityManagerNative.getDefault().serviceDoneExecuting(
2261 data.token, 1, data.startId, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 } catch (RemoteException e) {
2263 // nothing to do.
2264 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002265 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002266 } catch (Exception e) {
2267 if (!mInstrumentation.onException(s, e)) {
2268 throw new RuntimeException(
2269 "Unable to start service " + s
2270 + " with " + data.args + ": " + e.toString(), e);
2271 }
2272 }
2273 }
2274 }
2275
Romain Guy65b345f2011-07-27 18:51:50 -07002276 private void handleStopService(IBinder token) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002277 Service s = mServices.remove(token);
2278 if (s != null) {
2279 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002280 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281 s.onDestroy();
2282 Context context = s.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002283 if (context instanceof ContextImpl) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 final String who = s.getClassName();
Dianne Hackborn21556372010-02-04 16:34:40 -08002285 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002286 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002287
2288 QueuedWork.waitToFinish();
2289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002291 ActivityManagerNative.getDefault().serviceDoneExecuting(
2292 token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002293 } catch (RemoteException e) {
2294 // nothing to do.
2295 }
2296 } catch (Exception e) {
2297 if (!mInstrumentation.onException(s, e)) {
2298 throw new RuntimeException(
2299 "Unable to stop service " + s
2300 + ": " + e.toString(), e);
2301 }
2302 }
2303 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002304 //Slog.i(TAG, "Running services: " + mServices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002305 }
2306
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002307 public final ActivityClientRecord performResumeActivity(IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002308 boolean clearHide) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002309 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002310 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002311 + " finished=" + r.activity.mFinished);
2312 if (r != null && !r.activity.mFinished) {
2313 if (clearHide) {
2314 r.hideForNow = false;
2315 r.activity.mStartedActivity = false;
2316 }
2317 try {
2318 if (r.pendingIntents != null) {
2319 deliverNewIntents(r, r.pendingIntents);
2320 r.pendingIntents = null;
2321 }
2322 if (r.pendingResults != null) {
2323 deliverResults(r, r.pendingResults);
2324 r.pendingResults = null;
2325 }
2326 r.activity.performResume();
2327
Bob Leee5408332009-09-04 18:31:17 -07002328 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002329 r.activity.getComponentName().getClassName());
Bob Leee5408332009-09-04 18:31:17 -07002330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002331 r.paused = false;
2332 r.stopped = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002333 r.state = null;
2334 } catch (Exception e) {
2335 if (!mInstrumentation.onException(r.activity, e)) {
2336 throw new RuntimeException(
2337 "Unable to resume activity "
2338 + r.intent.getComponent().toShortString()
2339 + ": " + e.toString(), e);
2340 }
2341 }
2342 }
2343 return r;
2344 }
2345
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002346 final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
2347 if (r.mPendingRemoveWindow != null) {
2348 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2349 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2350 if (wtoken != null) {
2351 WindowManagerImpl.getDefault().closeAll(wtoken,
2352 r.activity.getClass().getName(), "Activity");
2353 }
2354 }
2355 r.mPendingRemoveWindow = null;
2356 r.mPendingRemoveWindowManager = null;
2357 }
2358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002359 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
2360 // If we are getting ready to gc after going to the background, well
2361 // we are back active so skip it.
2362 unscheduleGcIdler();
2363
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002364 ActivityClientRecord r = performResumeActivity(token, clearHide);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002365
2366 if (r != null) {
2367 final Activity a = r.activity;
2368
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002369 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002370 TAG, "Resume " + r + " started activity: " +
2371 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2372 + ", finished: " + a.mFinished);
2373
2374 final int forwardBit = isForward ?
2375 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
Bob Leee5408332009-09-04 18:31:17 -07002376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002377 // If the window hasn't yet been added to the window manager,
2378 // and this guy didn't finish itself or start another activity,
2379 // then go ahead and add the window.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002380 boolean willBeVisible = !a.mStartedActivity;
2381 if (!willBeVisible) {
2382 try {
2383 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2384 a.getActivityToken());
2385 } catch (RemoteException e) {
2386 }
2387 }
2388 if (r.window == null && !a.mFinished && willBeVisible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002389 r.window = r.activity.getWindow();
2390 View decor = r.window.getDecorView();
2391 decor.setVisibility(View.INVISIBLE);
2392 ViewManager wm = a.getWindowManager();
2393 WindowManager.LayoutParams l = r.window.getAttributes();
2394 a.mDecor = decor;
2395 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2396 l.softInputMode |= forwardBit;
2397 if (a.mVisibleFromClient) {
2398 a.mWindowAdded = true;
2399 wm.addView(decor, l);
2400 }
2401
2402 // If the window has already been added, but during resume
2403 // we started another activity, then don't yet make the
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002404 // window visible.
2405 } else if (!willBeVisible) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002406 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 TAG, "Launch " + r + " mStartedActivity set");
2408 r.hideForNow = true;
2409 }
2410
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002411 // Get rid of anything left hanging around.
2412 cleanUpPendingRemoveWindows(r);
2413
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002414 // The window is now visible if it has been added, we are not
2415 // simply finishing, and we are not starting another activity.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002416 if (!r.activity.mFinished && willBeVisible
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002417 && r.activity.mDecor != null && !r.hideForNow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002419 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002420 + r.activityInfo.name + " with newConfig " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002421 performConfigurationChanged(r.activity, r.newConfig);
2422 r.newConfig = null;
2423 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002424 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425 + isForward);
2426 WindowManager.LayoutParams l = r.window.getAttributes();
2427 if ((l.softInputMode
2428 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2429 != forwardBit) {
2430 l.softInputMode = (l.softInputMode
2431 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2432 | forwardBit;
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002433 if (r.activity.mVisibleFromClient) {
2434 ViewManager wm = a.getWindowManager();
2435 View decor = r.window.getDecorView();
2436 wm.updateViewLayout(decor, l);
2437 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002438 }
2439 r.activity.mVisibleFromServer = true;
2440 mNumVisibleActivities++;
2441 if (r.activity.mVisibleFromClient) {
2442 r.activity.makeVisible();
2443 }
2444 }
2445
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002446 if (!r.onlyLocalRequest) {
2447 r.nextIdle = mNewActivities;
2448 mNewActivities = r;
2449 if (localLOGV) Slog.v(
2450 TAG, "Scheduling idle handler for " + r);
2451 Looper.myQueue().addIdleHandler(new Idler());
2452 }
2453 r.onlyLocalRequest = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002454
2455 } else {
2456 // If an exception was thrown when trying to resume, then
2457 // just end this activity.
2458 try {
2459 ActivityManagerNative.getDefault()
2460 .finishActivity(token, Activity.RESULT_CANCELED, null);
2461 } catch (RemoteException ex) {
2462 }
2463 }
2464 }
2465
2466 private int mThumbnailWidth = -1;
2467 private int mThumbnailHeight = -1;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002468 private Bitmap mAvailThumbnailBitmap = null;
2469 private Canvas mThumbnailCanvas = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002470
Romain Guy65b345f2011-07-27 18:51:50 -07002471 private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002472 Bitmap thumbnail = mAvailThumbnailBitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002473 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002474 if (thumbnail == null) {
2475 int w = mThumbnailWidth;
2476 int h;
2477 if (w < 0) {
2478 Resources res = r.activity.getResources();
2479 mThumbnailHeight = h =
2480 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002481
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002482 mThumbnailWidth = w =
2483 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2484 } else {
2485 h = mThumbnailHeight;
2486 }
2487
2488 // On platforms where we don't want thumbnails, set dims to (0,0)
2489 if ((w > 0) && (h > 0)) {
2490 thumbnail = Bitmap.createBitmap(w, h, THUMBNAIL_FORMAT);
2491 thumbnail.eraseColor(0);
2492 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002493 }
2494
Dianne Hackbornfb3806d2010-12-09 13:14:12 -08002495 if (thumbnail != null) {
2496 Canvas cv = mThumbnailCanvas;
2497 if (cv == null) {
2498 mThumbnailCanvas = cv = new Canvas();
2499 }
2500
2501 cv.setBitmap(thumbnail);
2502 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2503 mAvailThumbnailBitmap = thumbnail;
2504 thumbnail = null;
2505 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002506 }
Jim Miller0b2a6d02010-07-13 18:01:29 -07002507
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002508 } catch (Exception e) {
2509 if (!mInstrumentation.onException(r.activity, e)) {
2510 throw new RuntimeException(
2511 "Unable to create thumbnail of "
2512 + r.intent.getComponent().toShortString()
2513 + ": " + e.toString(), e);
2514 }
2515 thumbnail = null;
2516 }
2517
2518 return thumbnail;
2519 }
2520
Romain Guy65b345f2011-07-27 18:51:50 -07002521 private void handlePauseActivity(IBinder token, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002522 boolean userLeaving, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002523 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002525 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002526 if (userLeaving) {
2527 performUserLeavingActivity(r);
2528 }
Bob Leee5408332009-09-04 18:31:17 -07002529
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002530 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002531 performPauseActivity(token, finished, r.isPreHoneycomb());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002532
Dianne Hackbornaa93bcd2010-10-27 13:57:00 -07002533 // Make sure any pending writes are now committed.
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002534 if (r.isPreHoneycomb()) {
2535 QueuedWork.waitToFinish();
2536 }
Dianne Hackbornaa93bcd2010-10-27 13:57:00 -07002537
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002538 // Tell the activity manager we have paused.
2539 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002540 ActivityManagerNative.getDefault().activityPaused(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002541 } catch (RemoteException ex) {
2542 }
2543 }
2544 }
2545
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002546 final void performUserLeavingActivity(ActivityClientRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002547 mInstrumentation.callActivityOnUserLeaving(r.activity);
2548 }
2549
2550 final Bundle performPauseActivity(IBinder token, boolean finished,
2551 boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002552 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002553 return r != null ? performPauseActivity(r, finished, saveState) : null;
2554 }
2555
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002556 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002557 boolean saveState) {
2558 if (r.paused) {
2559 if (r.activity.mFinished) {
2560 // If we are finishing, we won't call onResume() in certain cases.
2561 // So here we likewise don't want to call onPause() if the activity
2562 // isn't resumed.
2563 return null;
2564 }
2565 RuntimeException e = new RuntimeException(
2566 "Performing pause of activity that is not resumed: "
2567 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002568 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 }
2570 Bundle state = null;
2571 if (finished) {
2572 r.activity.mFinished = true;
2573 }
2574 try {
2575 // Next have the activity save its current state and managed dialogs...
2576 if (!r.activity.mFinished && saveState) {
2577 state = new Bundle();
2578 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2579 r.state = state;
2580 }
2581 // Now we are idle.
2582 r.activity.mCalled = false;
2583 mInstrumentation.callActivityOnPause(r.activity);
2584 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
2585 if (!r.activity.mCalled) {
2586 throw new SuperNotCalledException(
2587 "Activity " + r.intent.getComponent().toShortString() +
2588 " did not call through to super.onPause()");
2589 }
2590
2591 } catch (SuperNotCalledException e) {
2592 throw e;
2593
2594 } catch (Exception e) {
2595 if (!mInstrumentation.onException(r.activity, e)) {
2596 throw new RuntimeException(
2597 "Unable to pause activity "
2598 + r.intent.getComponent().toShortString()
2599 + ": " + e.toString(), e);
2600 }
2601 }
2602 r.paused = true;
Jeff Hamilton52d32032011-01-08 15:31:26 -06002603
2604 // Notify any outstanding on paused listeners
2605 ArrayList<OnActivityPausedListener> listeners;
2606 synchronized (mOnPauseListeners) {
2607 listeners = mOnPauseListeners.remove(r.activity);
2608 }
2609 int size = (listeners != null ? listeners.size() : 0);
2610 for (int i = 0; i < size; i++) {
2611 listeners.get(i).onPaused(r.activity);
2612 }
2613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002614 return state;
2615 }
2616
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002617 final void performStopActivity(IBinder token, boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002618 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002619 performStopActivityInner(r, null, false, saveState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002620 }
2621
2622 private static class StopInfo {
2623 Bitmap thumbnail;
2624 CharSequence description;
2625 }
2626
Romain Guy65b345f2011-07-27 18:51:50 -07002627 private class ProviderRefCount {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002628 public int count;
2629 ProviderRefCount(int pCount) {
2630 count = pCount;
2631 }
2632 }
2633
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002634 /**
2635 * Core implementation of stopping an activity. Note this is a little
2636 * tricky because the server's meaning of stop is slightly different
2637 * than our client -- for the server, stop means to save state and give
2638 * it the result when it is done, but the window may still be visible.
2639 * For the client, we want to call onStop()/onStart() to indicate when
2640 * the activity's UI visibillity changes.
2641 */
Romain Guy65b345f2011-07-27 18:51:50 -07002642 private void performStopActivityInner(ActivityClientRecord r,
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002643 StopInfo info, boolean keepShown, boolean saveState) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002644 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002645 Bundle state = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002646 if (r != null) {
2647 if (!keepShown && r.stopped) {
2648 if (r.activity.mFinished) {
2649 // If we are finishing, we won't call onResume() in certain
2650 // cases. So here we likewise don't want to call onStop()
2651 // if the activity isn't resumed.
2652 return;
2653 }
2654 RuntimeException e = new RuntimeException(
2655 "Performing stop of activity that is not resumed: "
2656 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002657 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002658 }
2659
2660 if (info != null) {
2661 try {
2662 // First create a thumbnail for the activity...
Jim Miller0b2a6d02010-07-13 18:01:29 -07002663 info.thumbnail = createThumbnailBitmap(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002664 info.description = r.activity.onCreateDescription();
2665 } catch (Exception e) {
2666 if (!mInstrumentation.onException(r.activity, e)) {
2667 throw new RuntimeException(
2668 "Unable to save state of activity "
2669 + r.intent.getComponent().toShortString()
2670 + ": " + e.toString(), e);
2671 }
2672 }
2673 }
2674
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002675 // Next have the activity save its current state and managed dialogs...
2676 if (!r.activity.mFinished && saveState) {
2677 if (r.state == null) {
2678 state = new Bundle();
2679 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2680 r.state = state;
2681 } else {
2682 state = r.state;
2683 }
2684 }
2685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002686 if (!keepShown) {
2687 try {
2688 // Now we are idle.
2689 r.activity.performStop();
2690 } catch (Exception e) {
2691 if (!mInstrumentation.onException(r.activity, e)) {
2692 throw new RuntimeException(
2693 "Unable to stop activity "
2694 + r.intent.getComponent().toShortString()
2695 + ": " + e.toString(), e);
2696 }
2697 }
2698 r.stopped = true;
2699 }
2700
2701 r.paused = true;
2702 }
2703 }
2704
Romain Guy65b345f2011-07-27 18:51:50 -07002705 private void updateVisibility(ActivityClientRecord r, boolean show) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002706 View v = r.activity.mDecor;
2707 if (v != null) {
2708 if (show) {
2709 if (!r.activity.mVisibleFromServer) {
2710 r.activity.mVisibleFromServer = true;
2711 mNumVisibleActivities++;
2712 if (r.activity.mVisibleFromClient) {
2713 r.activity.makeVisible();
2714 }
2715 }
2716 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002717 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002718 + r.activityInfo.name + " with new config " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002719 performConfigurationChanged(r.activity, r.newConfig);
2720 r.newConfig = null;
2721 }
2722 } else {
2723 if (r.activity.mVisibleFromServer) {
2724 r.activity.mVisibleFromServer = false;
2725 mNumVisibleActivities--;
2726 v.setVisibility(View.INVISIBLE);
2727 }
2728 }
2729 }
2730 }
2731
Romain Guy65b345f2011-07-27 18:51:50 -07002732 private void handleStopActivity(IBinder token, boolean show, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002733 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002734 r.activity.mConfigChangeFlags |= configChanges;
2735
2736 StopInfo info = new StopInfo();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002737 performStopActivityInner(r, info, show, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002738
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002739 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002740 TAG, "Finishing stop of " + r + ": show=" + show
2741 + " win=" + r.window);
2742
2743 updateVisibility(r, show);
Bob Leee5408332009-09-04 18:31:17 -07002744
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002745 // Make sure any pending writes are now committed.
2746 if (!r.isPreHoneycomb()) {
2747 QueuedWork.waitToFinish();
2748 }
2749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002750 // Tell activity manager we have been stopped.
2751 try {
2752 ActivityManagerNative.getDefault().activityStopped(
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002753 r.token, r.state, info.thumbnail, info.description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002754 } catch (RemoteException ex) {
2755 }
2756 }
2757
2758 final void performRestartActivity(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002759 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002760 if (r.stopped) {
2761 r.activity.performRestart();
2762 r.stopped = false;
2763 }
2764 }
2765
Romain Guy65b345f2011-07-27 18:51:50 -07002766 private void handleWindowVisibility(IBinder token, boolean show) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002767 ActivityClientRecord r = mActivities.get(token);
Dianne Hackbornbfddc0f2010-12-14 11:28:01 -08002768
2769 if (r == null) {
2770 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
2771 return;
2772 }
2773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 if (!show && !r.stopped) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002775 performStopActivityInner(r, null, show, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002776 } else if (show && r.stopped) {
2777 // If we are getting ready to gc after going to the background, well
2778 // we are back active so skip it.
2779 unscheduleGcIdler();
2780
2781 r.activity.performRestart();
2782 r.stopped = false;
2783 }
2784 if (r.activity.mDecor != null) {
Joe Onorato43a17652011-04-06 19:22:23 -07002785 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002786 TAG, "Handle window " + r + " visibility: " + show);
2787 updateVisibility(r, show);
2788 }
2789 }
2790
Romain Guy65b345f2011-07-27 18:51:50 -07002791 private void handleSleeping(IBinder token, boolean sleeping) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002792 ActivityClientRecord r = mActivities.get(token);
2793
2794 if (r == null) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08002795 Log.w(TAG, "handleSleeping: no activity for token " + token);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002796 return;
2797 }
2798
2799 if (sleeping) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08002800 if (!r.stopped && !r.isPreHoneycomb()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002801 try {
2802 // Now we are idle.
2803 r.activity.performStop();
2804 } catch (Exception e) {
2805 if (!mInstrumentation.onException(r.activity, e)) {
2806 throw new RuntimeException(
2807 "Unable to stop activity "
2808 + r.intent.getComponent().toShortString()
2809 + ": " + e.toString(), e);
2810 }
2811 }
2812 r.stopped = true;
2813 }
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002814
2815 // Make sure any pending writes are now committed.
2816 if (!r.isPreHoneycomb()) {
2817 QueuedWork.waitToFinish();
2818 }
2819
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002820 // Tell activity manager we slept.
2821 try {
2822 ActivityManagerNative.getDefault().activitySlept(r.token);
2823 } catch (RemoteException ex) {
2824 }
2825 } else {
2826 if (r.stopped && r.activity.mVisibleFromServer) {
2827 r.activity.performRestart();
2828 r.stopped = false;
2829 }
2830 }
2831 }
2832
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08002833 private void handleSetCoreSettings(Bundle coreSettings) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08002834 synchronized (mPackages) {
2835 mCoreSettings = coreSettings;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08002836 }
2837 }
2838
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002839 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) {
2840 LoadedApk apk = peekPackageInfo(data.pkg, false);
2841 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002842 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002843 }
2844 apk = peekPackageInfo(data.pkg, true);
2845 if (apk != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002846 apk.mCompatibilityInfo.set(data.info);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002847 }
2848 handleConfigurationChanged(mConfiguration, data.info);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07002849 WindowManagerImpl.getDefault().reportNewConfiguration(mConfiguration);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04002850 }
2851
Romain Guy65b345f2011-07-27 18:51:50 -07002852 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002853 final int N = results.size();
2854 for (int i=0; i<N; i++) {
2855 ResultInfo ri = results.get(i);
2856 try {
2857 if (ri.mData != null) {
2858 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
2859 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002860 if (DEBUG_RESULTS) Slog.v(TAG,
Chris Tate8a7dc172009-03-24 20:11:42 -07002861 "Delivering result to activity " + r + " : " + ri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002862 r.activity.dispatchActivityResult(ri.mResultWho,
2863 ri.mRequestCode, ri.mResultCode, ri.mData);
2864 } catch (Exception e) {
2865 if (!mInstrumentation.onException(r.activity, e)) {
2866 throw new RuntimeException(
2867 "Failure delivering result " + ri + " to activity "
2868 + r.intent.getComponent().toShortString()
2869 + ": " + e.toString(), e);
2870 }
2871 }
2872 }
2873 }
2874
Romain Guy65b345f2011-07-27 18:51:50 -07002875 private void handleSendResult(ResultData res) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002876 ActivityClientRecord r = mActivities.get(res.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002877 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002878 if (r != null) {
2879 final boolean resumed = !r.paused;
2880 if (!r.activity.mFinished && r.activity.mDecor != null
2881 && r.hideForNow && resumed) {
2882 // We had hidden the activity because it started another
2883 // one... we have gotten a result back and we are not
2884 // paused, so make sure our window is visible.
2885 updateVisibility(r, true);
2886 }
2887 if (resumed) {
2888 try {
2889 // Now we are idle.
2890 r.activity.mCalled = false;
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002891 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002892 mInstrumentation.callActivityOnPause(r.activity);
2893 if (!r.activity.mCalled) {
2894 throw new SuperNotCalledException(
2895 "Activity " + r.intent.getComponent().toShortString()
2896 + " did not call through to super.onPause()");
2897 }
2898 } catch (SuperNotCalledException e) {
2899 throw e;
2900 } catch (Exception e) {
2901 if (!mInstrumentation.onException(r.activity, e)) {
2902 throw new RuntimeException(
2903 "Unable to pause activity "
2904 + r.intent.getComponent().toShortString()
2905 + ": " + e.toString(), e);
2906 }
2907 }
2908 }
2909 deliverResults(r, res.results);
2910 if (resumed) {
Dianne Hackbornb46ed762011-06-02 18:33:15 -07002911 r.activity.performResume();
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002912 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002913 }
2914 }
2915 }
2916
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002917 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002918 return performDestroyActivity(token, finishing, 0, false);
2919 }
2920
Romain Guy65b345f2011-07-27 18:51:50 -07002921 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002923 ActivityClientRecord r = mActivities.get(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002924 Class activityClass = null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002925 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002926 if (r != null) {
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002927 activityClass = r.activity.getClass();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002928 r.activity.mConfigChangeFlags |= configChanges;
2929 if (finishing) {
2930 r.activity.mFinished = true;
2931 }
2932 if (!r.paused) {
2933 try {
2934 r.activity.mCalled = false;
2935 mInstrumentation.callActivityOnPause(r.activity);
Bob Leee5408332009-09-04 18:31:17 -07002936 EventLog.writeEvent(LOG_ON_PAUSE_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 r.activity.getComponentName().getClassName());
2938 if (!r.activity.mCalled) {
2939 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002940 "Activity " + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002941 + " did not call through to super.onPause()");
2942 }
2943 } catch (SuperNotCalledException e) {
2944 throw e;
2945 } catch (Exception e) {
2946 if (!mInstrumentation.onException(r.activity, e)) {
2947 throw new RuntimeException(
2948 "Unable to pause activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002949 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002950 + ": " + e.toString(), e);
2951 }
2952 }
2953 r.paused = true;
2954 }
2955 if (!r.stopped) {
2956 try {
2957 r.activity.performStop();
2958 } catch (SuperNotCalledException e) {
2959 throw e;
2960 } catch (Exception e) {
2961 if (!mInstrumentation.onException(r.activity, e)) {
2962 throw new RuntimeException(
2963 "Unable to stop activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002964 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002965 + ": " + e.toString(), e);
2966 }
2967 }
2968 r.stopped = true;
2969 }
2970 if (getNonConfigInstance) {
2971 try {
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002972 r.lastNonConfigurationInstances
2973 = r.activity.retainNonConfigurationInstances();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002974 } catch (Exception e) {
2975 if (!mInstrumentation.onException(r.activity, e)) {
2976 throw new RuntimeException(
2977 "Unable to retain activity "
2978 + r.intent.getComponent().toShortString()
2979 + ": " + e.toString(), e);
2980 }
2981 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002982 }
2983 try {
2984 r.activity.mCalled = false;
Dianne Hackborn2dedce62010-04-15 14:45:25 -07002985 mInstrumentation.callActivityOnDestroy(r.activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002986 if (!r.activity.mCalled) {
2987 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002988 "Activity " + safeToComponentShortString(r.intent) +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002989 " did not call through to super.onDestroy()");
2990 }
2991 if (r.window != null) {
2992 r.window.closeAllPanels();
2993 }
2994 } catch (SuperNotCalledException e) {
2995 throw e;
2996 } catch (Exception e) {
2997 if (!mInstrumentation.onException(r.activity, e)) {
2998 throw new RuntimeException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002999 "Unable to destroy activity " + safeToComponentShortString(r.intent)
3000 + ": " + e.toString(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003001 }
3002 }
3003 }
3004 mActivities.remove(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08003005 StrictMode.decrementExpectedActivityCount(activityClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003006 return r;
3007 }
3008
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07003009 private static String safeToComponentShortString(Intent intent) {
3010 ComponentName component = intent.getComponent();
3011 return component == null ? "[Unknown]" : component.toShortString();
3012 }
3013
Romain Guy65b345f2011-07-27 18:51:50 -07003014 private void handleDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003015 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003016 ActivityClientRecord r = performDestroyActivity(token, finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003017 configChanges, getNonConfigInstance);
3018 if (r != null) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003019 cleanUpPendingRemoveWindows(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003020 WindowManager wm = r.activity.getWindowManager();
3021 View v = r.activity.mDecor;
3022 if (v != null) {
3023 if (r.activity.mVisibleFromServer) {
3024 mNumVisibleActivities--;
3025 }
3026 IBinder wtoken = v.getWindowToken();
3027 if (r.activity.mWindowAdded) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003028 if (r.onlyLocalRequest) {
3029 // Hold off on removing this until the new activity's
3030 // window is being added.
3031 r.mPendingRemoveWindow = v;
3032 r.mPendingRemoveWindowManager = wm;
3033 } else {
3034 wm.removeViewImmediate(v);
3035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003036 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003037 if (wtoken != null && r.mPendingRemoveWindow == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003038 WindowManagerImpl.getDefault().closeAll(wtoken,
3039 r.activity.getClass().getName(), "Activity");
3040 }
3041 r.activity.mDecor = null;
3042 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003043 if (r.mPendingRemoveWindow == null) {
3044 // If we are delaying the removal of the activity window, then
3045 // we can't clean up all windows here. Note that we can't do
3046 // so later either, which means any windows that aren't closed
3047 // by the app will leak. Well we try to warning them a lot
3048 // about leaking windows, because that is a bug, so if they are
3049 // using this recreate facility then they get to live with leaks.
3050 WindowManagerImpl.getDefault().closeAll(token,
3051 r.activity.getClass().getName(), "Activity");
3052 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003053
3054 // Mocked out contexts won't be participating in the normal
3055 // process lifecycle, but if we're running with a proper
3056 // ApplicationContext we need to have it tear down things
3057 // cleanly.
3058 Context c = r.activity.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08003059 if (c instanceof ContextImpl) {
3060 ((ContextImpl) c).scheduleFinalCleanup(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003061 r.activity.getClass().getName(), "Activity");
3062 }
3063 }
3064 if (finishing) {
3065 try {
3066 ActivityManagerNative.getDefault().activityDestroyed(token);
3067 } catch (RemoteException ex) {
3068 // If the system process has died, it's game over for everyone.
3069 }
3070 }
3071 }
3072
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003073 public final void requestRelaunchActivity(IBinder token,
3074 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
3075 int configChanges, boolean notResumed, Configuration config,
3076 boolean fromServer) {
3077 ActivityClientRecord target = null;
3078
3079 synchronized (mPackages) {
3080 for (int i=0; i<mRelaunchingActivities.size(); i++) {
3081 ActivityClientRecord r = mRelaunchingActivities.get(i);
3082 if (r.token == token) {
3083 target = r;
3084 if (pendingResults != null) {
3085 if (r.pendingResults != null) {
3086 r.pendingResults.addAll(pendingResults);
3087 } else {
3088 r.pendingResults = pendingResults;
3089 }
3090 }
3091 if (pendingNewIntents != null) {
3092 if (r.pendingIntents != null) {
3093 r.pendingIntents.addAll(pendingNewIntents);
3094 } else {
3095 r.pendingIntents = pendingNewIntents;
3096 }
3097 }
3098 break;
3099 }
3100 }
3101
3102 if (target == null) {
3103 target = new ActivityClientRecord();
3104 target.token = token;
3105 target.pendingResults = pendingResults;
3106 target.pendingIntents = pendingNewIntents;
3107 if (!fromServer) {
3108 ActivityClientRecord existing = mActivities.get(token);
3109 if (existing != null) {
3110 target.startsNotResumed = existing.paused;
3111 }
3112 target.onlyLocalRequest = true;
3113 }
3114 mRelaunchingActivities.add(target);
3115 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
3116 }
3117
3118 if (fromServer) {
3119 target.startsNotResumed = notResumed;
3120 target.onlyLocalRequest = false;
3121 }
3122 if (config != null) {
3123 target.createdConfig = config;
3124 }
3125 target.pendingConfigChanges |= configChanges;
3126 }
3127 }
3128
Romain Guy65b345f2011-07-27 18:51:50 -07003129 private void handleRelaunchActivity(ActivityClientRecord tmp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003130 // If we are getting ready to gc after going to the background, well
3131 // we are back active so skip it.
3132 unscheduleGcIdler();
3133
3134 Configuration changedConfig = null;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003135 int configChanges = 0;
Bob Leee5408332009-09-04 18:31:17 -07003136
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003137 // First: make sure we have the most recent configuration and most
3138 // recent version of the activity, or skip it if some previous call
3139 // had taken a more recent version.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003140 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003141 int N = mRelaunchingActivities.size();
3142 IBinder token = tmp.token;
3143 tmp = null;
3144 for (int i=0; i<N; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003145 ActivityClientRecord r = mRelaunchingActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003146 if (r.token == token) {
3147 tmp = r;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003148 configChanges |= tmp.pendingConfigChanges;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003149 mRelaunchingActivities.remove(i);
3150 i--;
3151 N--;
3152 }
3153 }
Bob Leee5408332009-09-04 18:31:17 -07003154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003155 if (tmp == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003156 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003157 return;
3158 }
Bob Leee5408332009-09-04 18:31:17 -07003159
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003160 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3161 + tmp.token + " with configChanges=0x"
3162 + Integer.toHexString(configChanges));
3163
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003164 if (mPendingConfiguration != null) {
3165 changedConfig = mPendingConfiguration;
3166 mPendingConfiguration = null;
3167 }
3168 }
Bob Leee5408332009-09-04 18:31:17 -07003169
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003170 if (tmp.createdConfig != null) {
3171 // If the activity manager is passing us its current config,
3172 // assume that is really what we want regardless of what we
3173 // may have pending.
3174 if (mConfiguration == null
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003175 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3176 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3177 if (changedConfig == null
3178 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3179 changedConfig = tmp.createdConfig;
3180 }
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003181 }
3182 }
3183
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003184 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003185 + tmp.token + ": changedConfig=" + changedConfig);
3186
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003187 // If there was a pending configuration change, execute it first.
3188 if (changedConfig != null) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003189 handleConfigurationChanged(changedConfig, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003190 }
Bob Leee5408332009-09-04 18:31:17 -07003191
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003192 ActivityClientRecord r = mActivities.get(tmp.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003193 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003194 if (r == null) {
3195 return;
3196 }
Bob Leee5408332009-09-04 18:31:17 -07003197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003198 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003199 r.onlyLocalRequest = tmp.onlyLocalRequest;
Christopher Tateb70f3df2009-04-07 16:07:59 -07003200 Intent currentIntent = r.activity.mIntent;
Bob Leee5408332009-09-04 18:31:17 -07003201
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003202 r.activity.mChangingConfigurations = true;
3203
Dianne Hackborne2b04802010-12-09 09:24:55 -08003204 // Need to ensure state is saved.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003205 if (!r.paused) {
Dianne Hackborne2b04802010-12-09 09:24:55 -08003206 performPauseActivity(r.token, false, r.isPreHoneycomb());
3207 }
3208 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3209 r.state = new Bundle();
3210 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003211 }
Bob Leee5408332009-09-04 18:31:17 -07003212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003213 handleDestroyActivity(r.token, false, configChanges, true);
Bob Leee5408332009-09-04 18:31:17 -07003214
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003215 r.activity = null;
3216 r.window = null;
3217 r.hideForNow = false;
3218 r.nextIdle = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07003219 // Merge any pending results and pending intents; don't just replace them
3220 if (tmp.pendingResults != null) {
3221 if (r.pendingResults == null) {
3222 r.pendingResults = tmp.pendingResults;
3223 } else {
3224 r.pendingResults.addAll(tmp.pendingResults);
3225 }
3226 }
3227 if (tmp.pendingIntents != null) {
3228 if (r.pendingIntents == null) {
3229 r.pendingIntents = tmp.pendingIntents;
3230 } else {
3231 r.pendingIntents.addAll(tmp.pendingIntents);
3232 }
3233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003234 r.startsNotResumed = tmp.startsNotResumed;
Bob Leee5408332009-09-04 18:31:17 -07003235
Christopher Tateb70f3df2009-04-07 16:07:59 -07003236 handleLaunchActivity(r, currentIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003237 }
3238
Romain Guy65b345f2011-07-27 18:51:50 -07003239 private void handleRequestThumbnail(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003240 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003241 Bitmap thumbnail = createThumbnailBitmap(r);
3242 CharSequence description = null;
3243 try {
3244 description = r.activity.onCreateDescription();
3245 } catch (Exception e) {
3246 if (!mInstrumentation.onException(r.activity, e)) {
3247 throw new RuntimeException(
3248 "Unable to create description of activity "
3249 + r.intent.getComponent().toShortString()
3250 + ": " + e.toString(), e);
3251 }
3252 }
3253 //System.out.println("Reporting top thumbnail " + thumbnail);
3254 try {
3255 ActivityManagerNative.getDefault().reportThumbnail(
3256 token, thumbnail, description);
3257 } catch (RemoteException ex) {
3258 }
3259 }
3260
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003261 ArrayList<ComponentCallbacks2> collectComponentCallbacksLocked(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003262 boolean allActivities, Configuration newConfig) {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003263 ArrayList<ComponentCallbacks2> callbacks
3264 = new ArrayList<ComponentCallbacks2>();
Bob Leee5408332009-09-04 18:31:17 -07003265
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003266 if (mActivities.size() > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003267 Iterator<ActivityClientRecord> it = mActivities.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003268 while (it.hasNext()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003269 ActivityClientRecord ar = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003270 Activity a = ar.activity;
3271 if (a != null) {
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003272 Configuration thisConfig = applyConfigCompatMainThread(newConfig,
3273 ar.packageInfo.mCompatibilityInfo.getIfNeeded());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003274 if (!ar.activity.mFinished && (allActivities ||
3275 (a != null && !ar.paused))) {
3276 // If the activity is currently resumed, its configuration
3277 // needs to change right now.
3278 callbacks.add(a);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003279 } else if (thisConfig != null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003280 // Otherwise, we will tell it about the change
3281 // the next time it is resumed or shown. Note that
3282 // the activity manager may, before then, decide the
3283 // activity needs to be destroyed to handle its new
3284 // configuration.
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003285 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Setting activity "
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003286 + ar.activityInfo.name + " newConfig=" + thisConfig);
3287 ar.newConfig = thisConfig;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003288 }
3289 }
3290 }
3291 }
3292 if (mServices.size() > 0) {
3293 Iterator<Service> it = mServices.values().iterator();
3294 while (it.hasNext()) {
3295 callbacks.add(it.next());
3296 }
3297 }
3298 synchronized (mProviderMap) {
3299 if (mLocalProviders.size() > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003300 Iterator<ProviderClientRecord> it = mLocalProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003301 while (it.hasNext()) {
3302 callbacks.add(it.next().mLocalProvider);
3303 }
3304 }
3305 }
3306 final int N = mAllApplications.size();
3307 for (int i=0; i<N; i++) {
3308 callbacks.add(mAllApplications.get(i));
3309 }
Bob Leee5408332009-09-04 18:31:17 -07003310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003311 return callbacks;
3312 }
Bob Leee5408332009-09-04 18:31:17 -07003313
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003314 private final void performConfigurationChanged(
3315 ComponentCallbacks2 cb, Configuration config) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 // Only for Activity objects, check that they actually call up to their
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003317 // superclass implementation. ComponentCallbacks2 is an interface, so
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 // we check the runtime type and act accordingly.
3319 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3320 if (activity != null) {
3321 activity.mCalled = false;
3322 }
Bob Leee5408332009-09-04 18:31:17 -07003323
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003324 boolean shouldChangeConfig = false;
3325 if ((activity == null) || (activity.mCurrentConfig == null)) {
3326 shouldChangeConfig = true;
3327 } else {
Bob Leee5408332009-09-04 18:31:17 -07003328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003329 // If the new config is the same as the config this Activity
3330 // is already running with then don't bother calling
3331 // onConfigurationChanged
3332 int diff = activity.mCurrentConfig.diff(config);
3333 if (diff != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003334 // If this activity doesn't handle any of the config changes
3335 // then don't bother calling onConfigurationChanged as we're
3336 // going to destroy it.
Dianne Hackborne6676352011-06-01 16:51:20 -07003337 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 shouldChangeConfig = true;
3339 }
3340 }
3341 }
Bob Leee5408332009-09-04 18:31:17 -07003342
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003343 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003344 + ": shouldChangeConfig=" + shouldChangeConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003345 if (shouldChangeConfig) {
3346 cb.onConfigurationChanged(config);
Bob Leee5408332009-09-04 18:31:17 -07003347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003348 if (activity != null) {
3349 if (!activity.mCalled) {
3350 throw new SuperNotCalledException(
3351 "Activity " + activity.getLocalClassName() +
3352 " did not call through to super.onConfigurationChanged()");
3353 }
3354 activity.mConfigChangeFlags = 0;
3355 activity.mCurrentConfig = new Configuration(config);
3356 }
3357 }
3358 }
3359
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003360 public final void applyConfigurationToResources(Configuration config) {
3361 synchronized (mPackages) {
3362 applyConfigurationToResourcesLocked(config, null);
3363 }
3364 }
3365
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003366 final boolean applyConfigurationToResourcesLocked(Configuration config,
3367 CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003368 if (mResConfiguration == null) {
3369 mResConfiguration = new Configuration();
3370 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003371 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003372 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003373 + mResConfiguration.seq + ", newSeq=" + config.seq);
Dianne Hackbornae078162010-03-18 11:29:37 -07003374 return false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003375 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003376 int changes = mResConfiguration.updateFrom(config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003377 DisplayMetrics dm = getDisplayMetricsLocked(compat, true);
3378
3379 if (compat != null && (mResCompatibilityInfo == null ||
3380 !mResCompatibilityInfo.equals(compat))) {
3381 mResCompatibilityInfo = compat;
3382 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT
3383 | ActivityInfo.CONFIG_SCREEN_SIZE
3384 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
3385 }
Bob Leee5408332009-09-04 18:31:17 -07003386
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003387 // set it for java, this also affects newly created Resources
3388 if (config.locale != null) {
3389 Locale.setDefault(config.locale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003390 }
Bob Leee5408332009-09-04 18:31:17 -07003391
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003392 Resources.updateSystemConfiguration(config, dm, compat);
Bob Leee5408332009-09-04 18:31:17 -07003393
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08003394 ApplicationPackageManager.configurationChanged();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003395 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003396
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003397 Iterator<WeakReference<Resources>> it =
3398 mActiveResources.values().iterator();
3399 //Iterator<Map.Entry<String, WeakReference<Resources>>> it =
3400 // mActiveResources.entrySet().iterator();
3401 while (it.hasNext()) {
3402 WeakReference<Resources> v = it.next();
3403 Resources r = v.get();
3404 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003405 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003406 + r + " config to: " + config);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003407 r.updateConfiguration(config, dm, compat);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003408 //Slog.i(TAG, "Updated app resources " + v.getKey()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003409 // + " " + r + ": " + r.getConfiguration());
3410 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003411 //Slog.i(TAG, "Removing old resources " + v.getKey());
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003412 it.remove();
3413 }
3414 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003415
3416 return changes != 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003417 }
3418
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003419 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003420
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003421 ArrayList<ComponentCallbacks2> callbacks = null;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003422
3423 synchronized (mPackages) {
3424 if (mPendingConfiguration != null) {
3425 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3426 config = mPendingConfiguration;
3427 }
3428 mPendingConfiguration = null;
3429 }
3430
3431 if (config == null) {
3432 return;
3433 }
3434
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003435 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003436 + config);
3437
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003438 applyConfigurationToResourcesLocked(config, compat);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003440 if (mConfiguration == null) {
3441 mConfiguration = new Configuration();
3442 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003443 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003444 return;
3445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003446 mConfiguration.updateFrom(config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003447 if (mCompatConfiguration == null) {
3448 mCompatConfiguration = new Configuration();
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003449 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003450 mCompatConfiguration.setTo(mConfiguration);
3451 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) {
3452 mResCompatibilityInfo.applyToConfiguration(mCompatConfiguration);
3453 config = mCompatConfiguration;
3454 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003455 callbacks = collectComponentCallbacksLocked(false, config);
3456 }
Romain Guy65b345f2011-07-27 18:51:50 -07003457
3458 // Cleanup hardware accelerated stuff
3459 WindowManagerImpl.getDefault().trimLocalMemory();
Bob Leee5408332009-09-04 18:31:17 -07003460
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003461 if (callbacks != null) {
3462 final int N = callbacks.size();
3463 for (int i=0; i<N; i++) {
3464 performConfigurationChanged(callbacks.get(i), config);
3465 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003466 }
3467 }
3468
3469 final void handleActivityConfigurationChanged(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003470 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003471 if (r == null || r.activity == null) {
3472 return;
3473 }
Bob Leee5408332009-09-04 18:31:17 -07003474
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003475 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003476 + r.activityInfo.name);
3477
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003478 performConfigurationChanged(r.activity, mCompatConfiguration);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003479 }
3480
Romain Guy7eabe552011-07-21 14:56:34 -07003481 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003482 if (start) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003483 try {
Romain Guy7eabe552011-07-21 14:56:34 -07003484 switch (profileType) {
3485 case 1:
3486 ViewDebug.startLooperProfiling(pcd.path, pcd.fd.getFileDescriptor());
3487 break;
3488 default:
3489 Debug.startMethodTracing(pcd.path, pcd.fd.getFileDescriptor(),
3490 8 * 1024 * 1024, 0);
3491 break;
3492 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003493 } catch (RuntimeException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003494 Slog.w(TAG, "Profiling failed on path " + pcd.path
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003495 + " -- can the process access this path?");
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003496 } finally {
3497 try {
3498 pcd.fd.close();
3499 } catch (IOException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003500 Slog.w(TAG, "Failure closing profile fd", e);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003501 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003502 }
3503 } else {
Romain Guy7eabe552011-07-21 14:56:34 -07003504 switch (profileType) {
3505 case 1:
3506 ViewDebug.stopLooperProfiling();
3507 break;
3508 default:
3509 Debug.stopMethodTracing();
3510 break;
3511
3512 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003513 }
3514 }
Bob Leee5408332009-09-04 18:31:17 -07003515
Andy McFadden824c5102010-07-09 16:26:57 -07003516 final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
3517 if (managed) {
3518 try {
3519 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
3520 } catch (IOException e) {
3521 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
3522 + " -- can the process access this path?");
3523 } finally {
3524 try {
3525 dhd.fd.close();
3526 } catch (IOException e) {
3527 Slog.w(TAG, "Failure closing profile fd", e);
3528 }
3529 }
3530 } else {
Andy McFadden06a6b552010-07-13 16:28:09 -07003531 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
Andy McFadden824c5102010-07-09 16:26:57 -07003532 }
3533 }
3534
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003535 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
3536 boolean hasPkgInfo = false;
3537 if (packages != null) {
3538 for (int i=packages.length-1; i>=0; i--) {
3539 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
3540 if (!hasPkgInfo) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003541 WeakReference<LoadedApk> ref;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003542 ref = mPackages.get(packages[i]);
3543 if (ref != null && ref.get() != null) {
3544 hasPkgInfo = true;
3545 } else {
3546 ref = mResourcePackages.get(packages[i]);
3547 if (ref != null && ref.get() != null) {
3548 hasPkgInfo = true;
3549 }
3550 }
3551 }
3552 mPackages.remove(packages[i]);
3553 mResourcePackages.remove(packages[i]);
3554 }
3555 }
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08003556 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003557 hasPkgInfo);
3558 }
3559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003560 final void handleLowMemory() {
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003561 ArrayList<ComponentCallbacks2> callbacks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003562
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003563 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003564 callbacks = collectComponentCallbacksLocked(true, null);
3565 }
Bob Leee5408332009-09-04 18:31:17 -07003566
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003567 final int N = callbacks.size();
3568 for (int i=0; i<N; i++) {
3569 callbacks.get(i).onLowMemory();
3570 }
3571
Chris Tatece229052009-03-25 16:44:52 -07003572 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
3573 if (Process.myUid() != Process.SYSTEM_UID) {
3574 int sqliteReleased = SQLiteDatabase.releaseMemory();
3575 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
3576 }
Bob Leee5408332009-09-04 18:31:17 -07003577
Mike Reedcaf0df12009-04-27 14:32:05 -04003578 // Ask graphics to free up as much as possible (font/image caches)
3579 Canvas.freeCaches();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003580
3581 BinderInternal.forceGc("mem");
3582 }
3583
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003584 final void handleTrimMemory(int level) {
Romain Guybdf76092011-07-18 15:00:43 -07003585 WindowManagerImpl.getDefault().trimMemory(level);
Dianne Hackbornc68c9132011-07-29 01:25:18 -07003586 ArrayList<ComponentCallbacks2> callbacks;
3587
3588 synchronized (mPackages) {
3589 callbacks = collectComponentCallbacksLocked(true, null);
3590 }
3591
3592 final int N = callbacks.size();
3593 for (int i=0; i<N; i++) {
3594 callbacks.get(i).onTrimMemory(level);
3595 }
Dianne Hackbornce86ba82011-07-13 19:33:41 -07003596 }
3597
Romain Guy65b345f2011-07-27 18:51:50 -07003598 private void handleBindApplication(AppBindData data) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003599 mBoundApplication = data;
3600 mConfiguration = new Configuration(data.config);
Dianne Hackborn5fd21692011-06-07 14:09:47 -07003601 mCompatConfiguration = new Configuration(data.config);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 // send up app name; do this *before* waiting for debugger
Christopher Tate8ee038d2009-11-06 11:30:20 -08003604 Process.setArgV0(data.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003605 android.ddm.DdmHandleAppName.setAppName(data.processName);
3606
Joe Onoratod630f102011-03-17 18:42:26 -07003607 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
3608 // implementation to use the pool executor. Normally, we use the
3609 // serialized executor as the default. This has to happen in the
3610 // main thread so the main looper is set right.
3611 if (data.appInfo.targetSdkVersion <= 12) {
3612 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
3613 }
3614
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003615 /*
3616 * Before spawning a new process, reset the time zone to be the system time zone.
3617 * This needs to be done because the system time zone could have changed after the
3618 * the spawning of this process. Without doing this this process would have the incorrect
3619 * system time zone.
3620 */
3621 TimeZone.setDefault(null);
3622
3623 /*
3624 * Initialize the default locale in this process for the reasons we set the time zone.
3625 */
3626 Locale.setDefault(data.config.locale);
3627
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07003628 /*
3629 * Update the system configuration since its preloaded and might not
3630 * reflect configuration changes. The configuration object passed
3631 * in AppBindData can be safely assumed to be up to date
3632 */
Dianne Hackborn2f0b1752011-05-31 17:59:49 -07003633 applyConfigurationToResourcesLocked(data.config, data.compatInfo);
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07003634
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003635 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003636
Dianne Hackborn96e240f2009-07-26 17:42:30 -07003637 /**
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07003638 * For system applications on userdebug/eng builds, log stack
3639 * traces of disk and network access to dropbox for analysis.
3640 */
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07003641 if ((data.appInfo.flags &
3642 (ApplicationInfo.FLAG_SYSTEM |
Brad Fitzpatrick50d66f92010-09-13 21:29:05 -07003643 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
3644 StrictMode.conditionallyEnableDebugLogging();
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07003645 }
3646
3647 /**
Brad Fitzpatrickb6e18412010-10-28 14:50:05 -07003648 * For apps targetting SDK Honeycomb or later, we don't allow
3649 * network usage on the main event loop / UI thread.
3650 *
3651 * Note to those grepping: this is what ultimately throws
3652 * NetworkOnMainThreadException ...
3653 */
3654 if (data.appInfo.targetSdkVersion > 9) {
3655 StrictMode.enableDeathOnNetwork();
3656 }
3657
3658 /**
Dianne Hackborn96e240f2009-07-26 17:42:30 -07003659 * Switch this process to density compatibility mode if needed.
3660 */
3661 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
3662 == 0) {
3663 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
3664 }
Bob Leee5408332009-09-04 18:31:17 -07003665
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003666 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
3667 // XXX should have option to change the port.
3668 Debug.changeDebugPort(8100);
3669 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003670 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 + " is waiting for the debugger on port 8100...");
3672
3673 IActivityManager mgr = ActivityManagerNative.getDefault();
3674 try {
3675 mgr.showWaitingForDebugger(mAppThread, true);
3676 } catch (RemoteException ex) {
3677 }
3678
3679 Debug.waitForDebugger();
3680
3681 try {
3682 mgr.showWaitingForDebugger(mAppThread, false);
3683 } catch (RemoteException ex) {
3684 }
3685
3686 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003687 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003688 + " can be debugged on port 8100...");
3689 }
3690 }
3691
Robert Greenwalt434203a2010-10-11 16:00:27 -07003692 /**
3693 * Initialize the default http proxy in this process for the reasons we set the time zone.
3694 */
3695 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
3696 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
3697 try {
3698 ProxyProperties proxyProperties = service.getProxy();
3699 Proxy.setHttpProxySystemProperty(proxyProperties);
3700 } catch (RemoteException e) {}
3701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003702 if (data.instrumentationName != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08003703 ContextImpl appContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003704 appContext.init(data.info, null, this);
3705 InstrumentationInfo ii = null;
3706 try {
3707 ii = appContext.getPackageManager().
3708 getInstrumentationInfo(data.instrumentationName, 0);
3709 } catch (PackageManager.NameNotFoundException e) {
3710 }
3711 if (ii == null) {
3712 throw new RuntimeException(
3713 "Unable to find instrumentation info for: "
3714 + data.instrumentationName);
3715 }
3716
3717 mInstrumentationAppDir = ii.sourceDir;
3718 mInstrumentationAppPackage = ii.packageName;
3719 mInstrumentedAppDir = data.info.getAppDir();
3720
3721 ApplicationInfo instrApp = new ApplicationInfo();
3722 instrApp.packageName = ii.packageName;
3723 instrApp.sourceDir = ii.sourceDir;
3724 instrApp.publicSourceDir = ii.publicSourceDir;
3725 instrApp.dataDir = ii.dataDir;
Kenny Root85387d72010-08-26 10:13:11 -07003726 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04003727 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003728 appContext.getClassLoader(), false, true);
Dianne Hackborn21556372010-02-04 16:34:40 -08003729 ContextImpl instrContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003730 instrContext.init(pi, null, this);
3731
3732 try {
3733 java.lang.ClassLoader cl = instrContext.getClassLoader();
3734 mInstrumentation = (Instrumentation)
3735 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
3736 } catch (Exception e) {
3737 throw new RuntimeException(
3738 "Unable to instantiate instrumentation "
3739 + data.instrumentationName + ": " + e.toString(), e);
3740 }
3741
3742 mInstrumentation.init(this, instrContext, appContext,
3743 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
3744
3745 if (data.profileFile != null && !ii.handleProfiling) {
3746 data.handlingProfiling = true;
3747 File file = new File(data.profileFile);
3748 file.getParentFile().mkdirs();
3749 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
3750 }
3751
3752 try {
3753 mInstrumentation.onCreate(data.instrumentationArgs);
3754 }
3755 catch (Exception e) {
3756 throw new RuntimeException(
3757 "Exception thrown in onCreate() of "
3758 + data.instrumentationName + ": " + e.toString(), e);
3759 }
3760
3761 } else {
3762 mInstrumentation = new Instrumentation();
3763 }
3764
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08003765 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
Dianne Hackbornde398512011-01-18 18:45:21 -08003766 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08003767 }
3768
Christopher Tate181fafa2009-05-14 11:12:14 -07003769 // If the app is being launched for full backup or restore, bring it up in
3770 // a restricted environment with the base application class.
Dianne Hackborn0be1f782009-11-09 12:30:12 -08003771 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003772 mInitialApplication = app;
3773
Christopher Tate75a99702011-05-18 16:28:19 -07003774 // don't bring up providers in restricted mode; they may depend on the
3775 // app's custom Application class
3776 if (!data.restrictedBackupMode){
3777 List<ProviderInfo> providers = data.providers;
3778 if (providers != null) {
3779 installContentProviders(app, providers);
3780 // For process that contains content providers, we want to
3781 // ensure that the JIT is enabled "at some point".
3782 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
3783 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003784 }
3785
3786 try {
3787 mInstrumentation.callApplicationOnCreate(app);
3788 } catch (Exception e) {
3789 if (!mInstrumentation.onException(app, e)) {
3790 throw new RuntimeException(
3791 "Unable to create application " + app.getClass().getName()
3792 + ": " + e.toString(), e);
3793 }
3794 }
3795 }
3796
3797 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
3798 IActivityManager am = ActivityManagerNative.getDefault();
3799 if (mBoundApplication.profileFile != null && mBoundApplication.handlingProfiling) {
3800 Debug.stopMethodTracing();
3801 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003802 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003803 // + ", app thr: " + mAppThread);
3804 try {
3805 am.finishInstrumentation(mAppThread, resultCode, results);
3806 } catch (RemoteException ex) {
3807 }
3808 }
3809
Romain Guy65b345f2011-07-27 18:51:50 -07003810 private void installContentProviders(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003811 Context context, List<ProviderInfo> providers) {
3812 final ArrayList<IActivityManager.ContentProviderHolder> results =
3813 new ArrayList<IActivityManager.ContentProviderHolder>();
3814
3815 Iterator<ProviderInfo> i = providers.iterator();
3816 while (i.hasNext()) {
3817 ProviderInfo cpi = i.next();
3818 StringBuilder buf = new StringBuilder(128);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07003819 buf.append("Pub ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003820 buf.append(cpi.authority);
3821 buf.append(": ");
3822 buf.append(cpi.name);
3823 Log.i(TAG, buf.toString());
3824 IContentProvider cp = installProvider(context, null, cpi, false);
3825 if (cp != null) {
3826 IActivityManager.ContentProviderHolder cph =
3827 new IActivityManager.ContentProviderHolder(cpi);
3828 cph.provider = cp;
3829 results.add(cph);
3830 // Don't ever unload this provider from the process.
3831 synchronized(mProviderMap) {
3832 mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
3833 }
3834 }
3835 }
3836
3837 try {
3838 ActivityManagerNative.getDefault().publishContentProviders(
3839 getApplicationThread(), results);
3840 } catch (RemoteException ex) {
3841 }
3842 }
3843
Romain Guy65b345f2011-07-27 18:51:50 -07003844 private IContentProvider getExistingProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003845 synchronized(mProviderMap) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003846 final ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003847 if (pr != null) {
3848 return pr.mProvider;
3849 }
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003850 return null;
3851 }
3852 }
3853
Romain Guy65b345f2011-07-27 18:51:50 -07003854 private IContentProvider getProvider(Context context, String name) {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003855 IContentProvider existing = getExistingProvider(context, name);
3856 if (existing != null) {
3857 return existing;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858 }
3859
3860 IActivityManager.ContentProviderHolder holder = null;
3861 try {
3862 holder = ActivityManagerNative.getDefault().getContentProvider(
3863 getApplicationThread(), name);
3864 } catch (RemoteException ex) {
3865 }
3866 if (holder == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003867 Slog.e(TAG, "Failed to find provider info for " + name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003868 return null;
3869 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003870
3871 IContentProvider prov = installProvider(context, holder.provider,
3872 holder.info, true);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003873 //Slog.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003874 if (holder.noReleaseNeeded || holder.provider == null) {
3875 // We are not going to release the provider if it is an external
3876 // provider that doesn't care about being released, or if it is
3877 // a local provider running in this process.
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003878 //Slog.i(TAG, "*** NO RELEASE NEEDED");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003879 synchronized(mProviderMap) {
3880 mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(10000));
3881 }
3882 }
3883 return prov;
3884 }
3885
3886 public final IContentProvider acquireProvider(Context c, String name) {
3887 IContentProvider provider = getProvider(c, name);
3888 if(provider == null)
3889 return null;
3890 IBinder jBinder = provider.asBinder();
3891 synchronized(mProviderMap) {
3892 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3893 if(prc == null) {
3894 mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
3895 } else {
3896 prc.count++;
3897 } //end else
3898 } //end synchronized
3899 return provider;
3900 }
3901
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003902 public final IContentProvider acquireExistingProvider(Context c, String name) {
3903 IContentProvider provider = getExistingProvider(c, name);
3904 if(provider == null)
3905 return null;
3906 IBinder jBinder = provider.asBinder();
3907 synchronized(mProviderMap) {
3908 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3909 if(prc == null) {
3910 mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
3911 } else {
3912 prc.count++;
3913 } //end else
3914 } //end synchronized
3915 return provider;
3916 }
3917
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003918 public final boolean releaseProvider(IContentProvider provider) {
3919 if(provider == null) {
3920 return false;
3921 }
3922 IBinder jBinder = provider.asBinder();
3923 synchronized(mProviderMap) {
3924 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3925 if(prc == null) {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003926 if(localLOGV) Slog.v(TAG, "releaseProvider::Weird shouldn't be here");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003927 return false;
3928 } else {
3929 prc.count--;
3930 if(prc.count == 0) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003931 // Schedule the actual remove asynchronously, since we
3932 // don't know the context this will be called in.
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003933 // TODO: it would be nice to post a delayed message, so
3934 // if we come back and need the same provider quickly
3935 // we will still have it available.
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003936 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, provider);
3937 mH.sendMessage(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003938 } //end if
3939 } //end else
3940 } //end synchronized
3941 return true;
3942 }
3943
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003944 final void completeRemoveProvider(IContentProvider provider) {
3945 IBinder jBinder = provider.asBinder();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003946 String name = null;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003947 synchronized(mProviderMap) {
3948 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3949 if(prc != null && prc.count == 0) {
3950 mProviderRefCountMap.remove(jBinder);
3951 //invoke removeProvider to dereference provider
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003952 name = removeProviderLocked(provider);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003953 }
3954 }
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003955
3956 if (name != null) {
3957 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003958 if(localLOGV) Slog.v(TAG, "removeProvider::Invoking " +
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003959 "ActivityManagerNative.removeContentProvider(" + name);
3960 ActivityManagerNative.getDefault().removeContentProvider(
3961 getApplicationThread(), name);
3962 } catch (RemoteException e) {
3963 //do nothing content provider object is dead any way
3964 } //end catch
3965 }
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003966 }
3967
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003968 public final String removeProviderLocked(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003969 if (provider == null) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003970 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003971 }
3972 IBinder providerBinder = provider.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003973
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003974 String name = null;
3975
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003976 // remove the provider from mProviderMap
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003977 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003978 while (iter.hasNext()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003979 ProviderClientRecord pr = iter.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003980 IBinder myBinder = pr.mProvider.asBinder();
3981 if (myBinder == providerBinder) {
3982 //find if its published by this process itself
3983 if(pr.mLocalProvider != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003984 if(localLOGV) Slog.i(TAG, "removeProvider::found local provider returning");
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003985 return name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003986 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003987 if(localLOGV) Slog.v(TAG, "removeProvider::Not local provider Unlinking " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003988 "death recipient");
3989 //content provider is in another process
3990 myBinder.unlinkToDeath(pr, 0);
3991 iter.remove();
3992 //invoke remove only once for the very first name seen
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003993 if(name == null) {
3994 name = pr.mName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 }
3996 } //end if myBinder
3997 } //end while iter
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003998
3999 return name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004000 }
4001
4002 final void removeDeadProvider(String name, IContentProvider provider) {
4003 synchronized(mProviderMap) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004004 ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004005 if (pr.mProvider.asBinder() == provider.asBinder()) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004006 Slog.i(TAG, "Removing dead content provider: " + name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004007 ProviderClientRecord removed = mProviderMap.remove(name);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004008 if (removed != null) {
4009 removed.mProvider.asBinder().unlinkToDeath(removed, 0);
4010 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004011 }
4012 }
4013 }
4014
4015 final void removeDeadProviderLocked(String name, IContentProvider provider) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004016 ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 if (pr.mProvider.asBinder() == provider.asBinder()) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004018 Slog.i(TAG, "Removing dead content provider: " + name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004019 ProviderClientRecord removed = mProviderMap.remove(name);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07004020 if (removed != null) {
4021 removed.mProvider.asBinder().unlinkToDeath(removed, 0);
4022 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004023 }
4024 }
4025
Romain Guy65b345f2011-07-27 18:51:50 -07004026 private IContentProvider installProvider(Context context,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004027 IContentProvider provider, ProviderInfo info, boolean noisy) {
4028 ContentProvider localProvider = null;
4029 if (provider == null) {
4030 if (noisy) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004031 Slog.d(TAG, "Loading provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004032 + info.name);
4033 }
4034 Context c = null;
4035 ApplicationInfo ai = info.applicationInfo;
4036 if (context.getPackageName().equals(ai.packageName)) {
4037 c = context;
4038 } else if (mInitialApplication != null &&
4039 mInitialApplication.getPackageName().equals(ai.packageName)) {
4040 c = mInitialApplication;
4041 } else {
4042 try {
4043 c = context.createPackageContext(ai.packageName,
4044 Context.CONTEXT_INCLUDE_CODE);
4045 } catch (PackageManager.NameNotFoundException e) {
Romain Guy65b345f2011-07-27 18:51:50 -07004046 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004047 }
4048 }
4049 if (c == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004050 Slog.w(TAG, "Unable to get context for package " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004051 ai.packageName +
4052 " while loading content provider " +
4053 info.name);
4054 return null;
4055 }
4056 try {
4057 final java.lang.ClassLoader cl = c.getClassLoader();
4058 localProvider = (ContentProvider)cl.
4059 loadClass(info.name).newInstance();
4060 provider = localProvider.getIContentProvider();
4061 if (provider == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08004062 Slog.e(TAG, "Failed to instantiate class " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004063 info.name + " from sourceDir " +
4064 info.applicationInfo.sourceDir);
4065 return null;
4066 }
Joe Onorato43a17652011-04-06 19:22:23 -07004067 if (false) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004068 TAG, "Instantiating local provider " + info.name);
4069 // XXX Need to create the correct context for this provider.
4070 localProvider.attachInfo(c, info);
4071 } catch (java.lang.Exception e) {
4072 if (!mInstrumentation.onException(null, e)) {
4073 throw new RuntimeException(
4074 "Unable to get provider " + info.name
4075 + ": " + e.toString(), e);
4076 }
4077 return null;
4078 }
4079 } else if (localLOGV) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004080 Slog.v(TAG, "Installing external provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004081 + info.name);
4082 }
4083
4084 synchronized (mProviderMap) {
4085 // Cache the pointer for the remote provider.
4086 String names[] = PATTERN_SEMICOLON.split(info.authority);
4087 for (int i=0; i<names.length; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004088 ProviderClientRecord pr = new ProviderClientRecord(names[i], provider,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004089 localProvider);
4090 try {
4091 provider.asBinder().linkToDeath(pr, 0);
4092 mProviderMap.put(names[i], pr);
4093 } catch (RemoteException e) {
4094 return null;
4095 }
4096 }
4097 if (localProvider != null) {
4098 mLocalProviders.put(provider.asBinder(),
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07004099 new ProviderClientRecord(null, provider, localProvider));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004100 }
4101 }
4102
4103 return provider;
4104 }
4105
Romain Guy65b345f2011-07-27 18:51:50 -07004106 private void attach(boolean system) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004107 sThreadLocal.set(this);
4108 mSystemThread = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004109 if (!system) {
Dianne Hackborn6dd005b2011-07-18 13:22:50 -07004110 ViewRootImpl.addFirstDrawHandler(new Runnable() {
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08004111 public void run() {
4112 ensureJitEnabled();
4113 }
4114 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004115 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
4116 RuntimeInit.setApplicationObject(mAppThread.asBinder());
4117 IActivityManager mgr = ActivityManagerNative.getDefault();
4118 try {
4119 mgr.attachApplication(mAppThread);
4120 } catch (RemoteException ex) {
Romain Guy65b345f2011-07-27 18:51:50 -07004121 // Ignore
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004122 }
4123 } else {
4124 // Don't set application object here -- if the system crashes,
4125 // we can't display an alert, we just want to die die die.
4126 android.ddm.DdmHandleAppName.setAppName("system_process");
4127 try {
4128 mInstrumentation = new Instrumentation();
Dianne Hackborn21556372010-02-04 16:34:40 -08004129 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004130 context.init(getSystemContext().mPackageInfo, null, this);
4131 Application app = Instrumentation.newApplication(Application.class, context);
4132 mAllApplications.add(app);
4133 mInitialApplication = app;
4134 app.onCreate();
4135 } catch (Exception e) {
4136 throw new RuntimeException(
4137 "Unable to instantiate Application():" + e.toString(), e);
4138 }
4139 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004140
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004141 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004142 public void onConfigurationChanged(Configuration newConfig) {
4143 synchronized (mPackages) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004144 // We need to apply this change to the resources
4145 // immediately, because upon returning the view
4146 // hierarchy will be informed about it.
Dianne Hackborne2515ee2011-04-27 18:52:56 -04004147 if (applyConfigurationToResourcesLocked(newConfig, null)) {
Dianne Hackbornae078162010-03-18 11:29:37 -07004148 // This actually changed the resources! Tell
4149 // everyone about it.
4150 if (mPendingConfiguration == null ||
4151 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
4152 mPendingConfiguration = newConfig;
4153
4154 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
4155 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004156 }
4157 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004158 }
4159 public void onLowMemory() {
4160 }
Dianne Hackbornc68c9132011-07-29 01:25:18 -07004161 public void onTrimMemory(int level) {
4162 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08004163 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004164 }
4165
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004166 public static final ActivityThread systemMain() {
Romain Guy52339202010-09-03 16:04:46 -07004167 HardwareRenderer.disable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004168 ActivityThread thread = new ActivityThread();
4169 thread.attach(true);
4170 return thread;
4171 }
4172
Jeff Brown10e89712011-07-08 18:52:57 -07004173 public final void installSystemProviders(List<ProviderInfo> providers) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004174 if (providers != null) {
Jeff Brown10e89712011-07-08 18:52:57 -07004175 installContentProviders(mInitialApplication, providers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 }
4177 }
4178
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004179 public int getIntCoreSetting(String key, int defaultValue) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08004180 synchronized (mPackages) {
4181 if (mCoreSettings != null) {
4182 return mCoreSettings.getInt(key, defaultValue);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004183 } else {
4184 return defaultValue;
4185 }
4186 }
4187 }
4188
Romain Guy65b345f2011-07-27 18:51:50 -07004189 public static void main(String[] args) {
Bob Leee5408332009-09-04 18:31:17 -07004190 SamplingProfilerIntegration.start();
4191
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -08004192 // CloseGuard defaults to true and can be quite spammy. We
4193 // disable it here, but selectively enable it later (via
4194 // StrictMode) on debug builds, but using DropBox, not logs.
4195 CloseGuard.setEnabled(false);
4196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004197 Process.setArgV0("<pre-initialized>");
4198
4199 Looper.prepareMainLooper();
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07004200 if (sMainThreadHandler == null) {
4201 sMainThreadHandler = new Handler();
4202 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004203
4204 ActivityThread thread = new ActivityThread();
4205 thread.attach(false);
4206
Dianne Hackborn287952c2010-09-22 22:34:31 -07004207 if (false) {
4208 Looper.myLooper().setMessageLogging(new
4209 LogPrinter(Log.DEBUG, "ActivityThread"));
4210 }
4211
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004212 Looper.loop();
4213
Jeff Brown10e89712011-07-08 18:52:57 -07004214 throw new RuntimeException("Main thread loop unexpectedly exited");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004215 }
4216}