blob: 751726a6b8c077d8e460b4c311d9011f892b4bf6 [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;
21import android.content.ComponentCallbacks;
22import 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;
63import android.util.Config;
64import android.util.DisplayMetrics;
65import android.util.EventLog;
66import android.util.Log;
Dianne Hackborn287952c2010-09-22 22:34:31 -070067import android.util.LogPrinter;
Dianne Hackbornc9421ba2010-03-11 22:23:46 -080068import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069import android.view.Display;
Romain Guy52339202010-09-03 16:04:46 -070070import android.view.HardwareRenderer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071import android.view.View;
72import android.view.ViewDebug;
73import android.view.ViewManager;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -080074import android.view.ViewRoot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080075import android.view.Window;
76import android.view.WindowManager;
77import android.view.WindowManagerImpl;
78
79import com.android.internal.os.BinderInternal;
80import com.android.internal.os.RuntimeInit;
Bob Leee5408332009-09-04 18:31:17 -070081import com.android.internal.os.SamplingProfilerIntegration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082
83import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
84
85import java.io.File;
86import java.io.FileDescriptor;
87import java.io.FileOutputStream;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070088import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import java.io.PrintWriter;
90import java.lang.ref.WeakReference;
Robert Greenwalt03595d02010-11-02 14:08:23 -070091import java.net.InetAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import java.util.ArrayList;
93import java.util.HashMap;
94import java.util.Iterator;
95import java.util.List;
96import java.util.Locale;
97import java.util.Map;
98import java.util.TimeZone;
99import java.util.regex.Pattern;
100
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -0800101import dalvik.system.CloseGuard;
Bob Leee5408332009-09-04 18:31:17 -0700102
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800103final class SuperNotCalledException extends AndroidRuntimeException {
104 public SuperNotCalledException(String msg) {
105 super(msg);
106 }
107}
108
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700109final class RemoteServiceException extends AndroidRuntimeException {
110 public RemoteServiceException(String msg) {
111 super(msg);
112 }
113}
114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115/**
116 * This manages the execution of the main thread in an
117 * application process, scheduling and executing activities,
118 * broadcasts, and other operations on it as the activity
119 * manager requests.
120 *
121 * {@hide}
122 */
123public final class ActivityThread {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700124 /** @hide */
125 public static final String TAG = "ActivityThread";
Jim Miller0b2a6d02010-07-13 18:01:29 -0700126 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 private static final boolean DEBUG = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700128 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700129 static final boolean DEBUG_MESSAGES = false;
Dianne Hackborne829fef2010-10-26 17:44:01 -0700130 /** @hide */
131 public static final boolean DEBUG_BROADCAST = false;
Chris Tate8a7dc172009-03-24 20:11:42 -0700132 private static final boolean DEBUG_RESULTS = false;
Christopher Tate436344a2009-09-30 16:17:37 -0700133 private static final boolean DEBUG_BACKUP = false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700134 private static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
136 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
137 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
138 private static final int LOG_ON_PAUSE_CALLED = 30021;
139 private static final int LOG_ON_RESUME_CALLED = 30022;
140
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700141 static ContextImpl mSystemContext = null;
Bob Leee5408332009-09-04 18:31:17 -0700142
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700143 static IPackageManager sPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700145 final ApplicationThread mAppThread = new ApplicationThread();
146 final Looper mLooper = Looper.myLooper();
147 final H mH = new H();
148 final HashMap<IBinder, ActivityClientRecord> mActivities
149 = new HashMap<IBinder, ActivityClientRecord>();
150 // List of new activities (via ActivityRecord.nextIdle) that should
151 // be reported when next we idle.
152 ActivityClientRecord mNewActivities = null;
153 // Number of activities that are currently visible on-screen.
154 int mNumVisibleActivities = 0;
155 final HashMap<IBinder, Service> mServices
156 = new HashMap<IBinder, Service>();
157 AppBindData mBoundApplication;
158 Configuration mConfiguration;
159 Configuration mResConfiguration;
160 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>();
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700165 static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal();
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.
176 final HashMap<String, WeakReference<LoadedApk>> mPackages
177 = new HashMap<String, WeakReference<LoadedApk>>();
178 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
179 = new HashMap<String, WeakReference<LoadedApk>>();
180 Display mDisplay = null;
181 DisplayMetrics mDisplayMetrics = null;
182 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
183 = new HashMap<ResourcesKey, WeakReference<Resources> >();
184 final ArrayList<ActivityClientRecord> mRelaunchingActivities
185 = new ArrayList<ActivityClientRecord>();
186 Configuration mPendingConfiguration = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800187
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700188 // The lock of mProviderMap protects the following variables.
189 final HashMap<String, ProviderClientRecord> mProviderMap
190 = new HashMap<String, ProviderClientRecord>();
191 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
192 = new HashMap<IBinder, ProviderRefCount>();
193 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
194 = new HashMap<IBinder, ProviderClientRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800195
Jeff Hamilton52d32032011-01-08 15:31:26 -0600196 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners
197 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>();
198
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700199 final GcIdler mGcIdler = new GcIdler();
200 boolean mGcIdlerScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800201
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700202 static Handler sMainThreadHandler; // set once in main()
203
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800204 Bundle mCoreSettings = null;
205
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700206 private static final class ActivityClientRecord {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 IBinder token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700208 int ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800209 Intent intent;
210 Bundle state;
211 Activity activity;
212 Window window;
213 Activity parent;
214 String embeddedID;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -0700215 Activity.NonConfigurationInstances lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800216 boolean paused;
217 boolean stopped;
218 boolean hideForNow;
219 Configuration newConfig;
Dianne Hackborne88846e2009-09-30 21:34:25 -0700220 Configuration createdConfig;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700221 ActivityClientRecord nextIdle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222
223 ActivityInfo activityInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700224 LoadedApk packageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225
226 List<ResultInfo> pendingResults;
227 List<Intent> pendingIntents;
228
229 boolean startsNotResumed;
230 boolean isForward;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800231 int pendingConfigChanges;
232 boolean onlyLocalRequest;
233
234 View mPendingRemoveWindow;
235 WindowManager mPendingRemoveWindowManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800236
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700237 ActivityClientRecord() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800238 parent = null;
239 embeddedID = null;
240 paused = false;
241 stopped = false;
242 hideForNow = false;
243 nextIdle = null;
244 }
245
Dianne Hackborn0aae2d42010-12-07 23:51:29 -0800246 public boolean isPreHoneycomb() {
247 if (activity != null) {
248 return activity.getApplicationInfo().targetSdkVersion
249 < android.os.Build.VERSION_CODES.HONEYCOMB;
250 }
251 return false;
252 }
253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800254 public String toString() {
255 ComponentName componentName = intent.getComponent();
256 return "ActivityRecord{"
257 + Integer.toHexString(System.identityHashCode(this))
258 + " token=" + token + " " + (componentName == null
259 ? "no component name" : componentName.toShortString())
260 + "}";
261 }
262 }
263
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700264 private final class ProviderClientRecord implements IBinder.DeathRecipient {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800265 final String mName;
266 final IContentProvider mProvider;
267 final ContentProvider mLocalProvider;
268
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700269 ProviderClientRecord(String name, IContentProvider provider,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800270 ContentProvider localProvider) {
271 mName = name;
272 mProvider = provider;
273 mLocalProvider = localProvider;
274 }
275
276 public void binderDied() {
277 removeDeadProvider(mName, mProvider);
278 }
279 }
280
281 private static final class NewIntentData {
282 List<Intent> intents;
283 IBinder token;
284 public String toString() {
285 return "NewIntentData{intents=" + intents + " token=" + token + "}";
286 }
287 }
288
Dianne Hackborne829fef2010-10-26 17:44:01 -0700289 private static final class ReceiverData extends BroadcastReceiver.PendingResult {
290 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
291 boolean ordered, boolean sticky, IBinder token) {
292 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, token);
293 this.intent = intent;
294 }
Robert Greenwalt434203a2010-10-11 16:00:27 -0700295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 Intent intent;
297 ActivityInfo info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800298 public String toString() {
299 return "ReceiverData{intent=" + intent + " packageName=" +
Dianne Hackborne829fef2010-10-26 17:44:01 -0700300 info.packageName + " resultCode=" + getResultCode()
301 + " resultData=" + getResultData() + " resultExtras="
302 + getResultExtras(false) + "}";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800303 }
304 }
305
Christopher Tate181fafa2009-05-14 11:12:14 -0700306 private static final class CreateBackupAgentData {
307 ApplicationInfo appInfo;
308 int backupMode;
309 public String toString() {
310 return "CreateBackupAgentData{appInfo=" + appInfo
311 + " backupAgent=" + appInfo.backupAgentName
312 + " mode=" + backupMode + "}";
313 }
314 }
Bob Leee5408332009-09-04 18:31:17 -0700315
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316 private static final class CreateServiceData {
317 IBinder token;
318 ServiceInfo info;
319 Intent intent;
320 public String toString() {
321 return "CreateServiceData{token=" + token + " className="
322 + info.name + " packageName=" + info.packageName
323 + " intent=" + intent + "}";
324 }
325 }
326
327 private static final class BindServiceData {
328 IBinder token;
329 Intent intent;
330 boolean rebind;
331 public String toString() {
332 return "BindServiceData{token=" + token + " intent=" + intent + "}";
333 }
334 }
335
336 private static final class ServiceArgsData {
337 IBinder token;
338 int startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700339 int flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 Intent args;
341 public String toString() {
342 return "ServiceArgsData{token=" + token + " startId=" + startId
343 + " args=" + args + "}";
344 }
345 }
346
347 private static final class AppBindData {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700348 LoadedApk info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800349 String processName;
350 ApplicationInfo appInfo;
351 List<ProviderInfo> providers;
352 ComponentName instrumentationName;
353 String profileFile;
354 Bundle instrumentationArgs;
355 IInstrumentationWatcher instrumentationWatcher;
356 int debugMode;
Christopher Tate181fafa2009-05-14 11:12:14 -0700357 boolean restrictedBackupMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 Configuration config;
359 boolean handlingProfiling;
360 public String toString() {
361 return "AppBindData{appInfo=" + appInfo + "}";
362 }
363 }
364
Dianne Hackborn625ac272010-09-17 18:29:22 -0700365 private static final class DumpComponentInfo {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 FileDescriptor fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700367 IBinder token;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800368 String prefix;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 String[] args;
370 boolean dumped;
371 }
372
373 private static final class ResultData {
374 IBinder token;
375 List<ResultInfo> results;
376 public String toString() {
377 return "ResultData{token=" + token + " results" + results + "}";
378 }
379 }
380
381 private static final class ContextCleanupInfo {
Dianne Hackborn21556372010-02-04 16:34:40 -0800382 ContextImpl context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 String what;
384 String who;
385 }
386
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700387 private static final class ProfilerControlData {
388 String path;
389 ParcelFileDescriptor fd;
390 }
391
Andy McFadden824c5102010-07-09 16:26:57 -0700392 private static final class DumpHeapData {
393 String path;
394 ParcelFileDescriptor fd;
395 }
396
Chet Haase9c1e23b2011-03-24 10:51:31 -0700397 native private void dumpGraphicsInfo(FileDescriptor fd);
398
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800399 private final class ApplicationThread extends ApplicationThreadNative {
400 private static final String HEAP_COLUMN = "%17s %8s %8s %8s %8s";
401 private static final String ONE_COUNT_COLUMN = "%17s %8d";
402 private static final String TWO_COUNT_COLUMNS = "%17s %8d %17s %8d";
Vasu Nori3c7131f2010-09-21 14:36:57 -0700403 private static final String TWO_COUNT_COLUMNS_DB = "%20s %8d %20s %8d";
404 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
Bob Leee5408332009-09-04 18:31:17 -0700405
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800406 // Formatting for checkin service - update version if row format changes
407 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
Bob Leee5408332009-09-04 18:31:17 -0700408
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409 public final void schedulePauseActivity(IBinder token, boolean finished,
410 boolean userLeaving, int configChanges) {
411 queueOrSendMessage(
412 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
413 token,
414 (userLeaving ? 1 : 0),
415 configChanges);
416 }
417
418 public final void scheduleStopActivity(IBinder token, boolean showWindow,
419 int configChanges) {
420 queueOrSendMessage(
421 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
422 token, 0, configChanges);
423 }
424
425 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
426 queueOrSendMessage(
427 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
428 token);
429 }
430
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800431 public final void scheduleSleeping(IBinder token, boolean sleeping) {
432 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0);
433 }
434
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800435 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
436 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
437 }
438
439 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
440 ResultData res = new ResultData();
441 res.token = token;
442 res.results = results;
443 queueOrSendMessage(H.SEND_RESULT, res);
444 }
445
446 // we use token to identify this activity without having to send the
447 // activity itself back to the activity manager. (matters more with ipc)
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700448 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800449 ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
450 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700451 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800452
453 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700454 r.ident = ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800455 r.intent = intent;
456 r.activityInfo = info;
457 r.state = state;
458
459 r.pendingResults = pendingResults;
460 r.pendingIntents = pendingNewIntents;
461
462 r.startsNotResumed = notResumed;
463 r.isForward = isForward;
464
465 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
466 }
467
468 public final void scheduleRelaunchActivity(IBinder token,
469 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
Dianne Hackborn871ecdc2009-12-11 15:24:33 -0800470 int configChanges, boolean notResumed, Configuration config) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -0800471 requestRelaunchActivity(token, pendingResults, pendingNewIntents,
472 configChanges, notResumed, config, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800473 }
474
475 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
476 NewIntentData data = new NewIntentData();
477 data.intents = intents;
478 data.token = token;
479
480 queueOrSendMessage(H.NEW_INTENT, data);
481 }
482
483 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
484 int configChanges) {
485 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
486 configChanges);
487 }
488
489 public final void scheduleReceiver(Intent intent, ActivityInfo info,
490 int resultCode, String data, Bundle extras, boolean sync) {
Dianne Hackborne829fef2010-10-26 17:44:01 -0700491 ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
492 sync, false, mAppThread.asBinder());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 r.info = info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800494 queueOrSendMessage(H.RECEIVER, r);
495 }
496
Christopher Tate181fafa2009-05-14 11:12:14 -0700497 public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode) {
498 CreateBackupAgentData d = new CreateBackupAgentData();
499 d.appInfo = app;
500 d.backupMode = backupMode;
501
502 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
503 }
504
505 public final void scheduleDestroyBackupAgent(ApplicationInfo app) {
506 CreateBackupAgentData d = new CreateBackupAgentData();
507 d.appInfo = app;
508
509 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
510 }
511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800512 public final void scheduleCreateService(IBinder token,
513 ServiceInfo info) {
514 CreateServiceData s = new CreateServiceData();
515 s.token = token;
516 s.info = info;
517
518 queueOrSendMessage(H.CREATE_SERVICE, s);
519 }
520
521 public final void scheduleBindService(IBinder token, Intent intent,
522 boolean rebind) {
523 BindServiceData s = new BindServiceData();
524 s.token = token;
525 s.intent = intent;
526 s.rebind = rebind;
527
528 queueOrSendMessage(H.BIND_SERVICE, s);
529 }
530
531 public final void scheduleUnbindService(IBinder token, Intent intent) {
532 BindServiceData s = new BindServiceData();
533 s.token = token;
534 s.intent = intent;
535
536 queueOrSendMessage(H.UNBIND_SERVICE, s);
537 }
538
539 public final void scheduleServiceArgs(IBinder token, int startId,
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700540 int flags ,Intent args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800541 ServiceArgsData s = new ServiceArgsData();
542 s.token = token;
543 s.startId = startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700544 s.flags = flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 s.args = args;
546
547 queueOrSendMessage(H.SERVICE_ARGS, s);
548 }
549
550 public final void scheduleStopService(IBinder token) {
551 queueOrSendMessage(H.STOP_SERVICE, token);
552 }
553
554 public final void bindApplication(String processName,
555 ApplicationInfo appInfo, List<ProviderInfo> providers,
556 ComponentName instrumentationName, String profileFile,
557 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
Christopher Tate181fafa2009-05-14 11:12:14 -0700558 int debugMode, boolean isRestrictedBackupMode, Configuration config,
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800559 Map<String, IBinder> services, Bundle coreSettings) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560
561 if (services != null) {
562 // Setup the service cache in the ServiceManager
563 ServiceManager.initServiceCache(services);
564 }
565
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800566 setCoreSettings(coreSettings);
567
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 AppBindData data = new AppBindData();
569 data.processName = processName;
570 data.appInfo = appInfo;
571 data.providers = providers;
572 data.instrumentationName = instrumentationName;
573 data.profileFile = profileFile;
574 data.instrumentationArgs = instrumentationArgs;
575 data.instrumentationWatcher = instrumentationWatcher;
576 data.debugMode = debugMode;
Christopher Tate181fafa2009-05-14 11:12:14 -0700577 data.restrictedBackupMode = isRestrictedBackupMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800578 data.config = config;
579 queueOrSendMessage(H.BIND_APPLICATION, data);
580 }
581
582 public final void scheduleExit() {
583 queueOrSendMessage(H.EXIT_APPLICATION, null);
584 }
585
Christopher Tate5e1ab332009-09-01 20:32:49 -0700586 public final void scheduleSuicide() {
587 queueOrSendMessage(H.SUICIDE, null);
588 }
589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 public void requestThumbnail(IBinder token) {
591 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
592 }
593
594 public void scheduleConfigurationChanged(Configuration config) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800595 synchronized (mPackages) {
596 if (mPendingConfiguration == null ||
597 mPendingConfiguration.isOtherSeqNewer(config)) {
598 mPendingConfiguration = config;
599 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 }
601 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
602 }
603
604 public void updateTimeZone() {
605 TimeZone.setDefault(null);
606 }
607
Robert Greenwalt03595d02010-11-02 14:08:23 -0700608 public void clearDnsCache() {
609 // a non-standard API to get this to libcore
610 InetAddress.clearDnsCache();
611 }
612
Robert Greenwalt434203a2010-10-11 16:00:27 -0700613 public void setHttpProxy(String host, String port, String exclList) {
614 Proxy.setHttpProxySystemProperty(host, port, exclList);
615 }
616
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800617 public void processInBackground() {
618 mH.removeMessages(H.GC_WHEN_IDLE);
619 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
620 }
621
622 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700623 DumpComponentInfo data = new DumpComponentInfo();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 data.fd = fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700625 data.token = servicetoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 data.args = args;
627 data.dumped = false;
628 queueOrSendMessage(H.DUMP_SERVICE, data);
629 synchronized (data) {
630 while (!data.dumped) {
631 try {
632 data.wait();
633 } catch (InterruptedException e) {
634 // no need to do anything here, we will keep waiting until
635 // dumped is set
636 }
637 }
638 }
639 }
640
641 // This function exists to make sure all receiver dispatching is
642 // correctly ordered, since these are one-way calls and the binder driver
643 // applies transaction ordering per object for such calls.
644 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
Dianne Hackborn68d881c2009-10-05 13:58:17 -0700645 int resultCode, String dataStr, Bundle extras, boolean ordered,
646 boolean sticky) throws RemoteException {
647 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800648 }
Bob Leee5408332009-09-04 18:31:17 -0700649
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800650 public void scheduleLowMemory() {
651 queueOrSendMessage(H.LOW_MEMORY, null);
652 }
653
654 public void scheduleActivityConfigurationChanged(IBinder token) {
655 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
656 }
657
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700658 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd) {
659 ProfilerControlData pcd = new ProfilerControlData();
660 pcd.path = path;
661 pcd.fd = fd;
662 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800663 }
664
Andy McFadden824c5102010-07-09 16:26:57 -0700665 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
666 DumpHeapData dhd = new DumpHeapData();
667 dhd.path = path;
668 dhd.fd = fd;
669 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
670 }
671
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700672 public void setSchedulingGroup(int group) {
673 // Note: do this immediately, since going into the foreground
674 // should happen regardless of what pending work we have to do
675 // and the activity manager will wait for us to report back that
676 // we are done before sending us to the background.
677 try {
678 Process.setProcessGroup(Process.myPid(), group);
679 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800680 Slog.w(TAG, "Failed setting process group to " + group, e);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700681 }
682 }
Bob Leee5408332009-09-04 18:31:17 -0700683
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700684 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
685 Debug.getMemoryInfo(outInfo);
686 }
Bob Leee5408332009-09-04 18:31:17 -0700687
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700688 public void dispatchPackageBroadcast(int cmd, String[] packages) {
689 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
690 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700691
692 public void scheduleCrash(String msg) {
693 queueOrSendMessage(H.SCHEDULE_CRASH, msg);
694 }
Dianne Hackborn625ac272010-09-17 18:29:22 -0700695
Dianne Hackborn30d71892010-12-11 10:37:55 -0800696 public void dumpActivity(FileDescriptor fd, IBinder activitytoken,
697 String prefix, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700698 DumpComponentInfo data = new DumpComponentInfo();
699 data.fd = fd;
700 data.token = activitytoken;
Dianne Hackborn30d71892010-12-11 10:37:55 -0800701 data.prefix = prefix;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700702 data.args = args;
703 data.dumped = false;
704 queueOrSendMessage(H.DUMP_ACTIVITY, data);
705 synchronized (data) {
706 while (!data.dumped) {
707 try {
708 data.wait();
709 } catch (InterruptedException e) {
710 // no need to do anything here, we will keep waiting until
711 // dumped is set
712 }
713 }
714 }
715 }
Chet Haase9c1e23b2011-03-24 10:51:31 -0700716
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800717 @Override
718 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Chet Haase9c1e23b2011-03-24 10:51:31 -0700719 if (args != null && args.length == 1 && args[0].equals("graphics")) {
720 pw.flush();
721 dumpGraphicsInfo(fd);
722 return;
723 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 long nativeMax = Debug.getNativeHeapSize() / 1024;
725 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
726 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
727
728 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
729 Debug.getMemoryInfo(memInfo);
730
731 final int nativeShared = memInfo.nativeSharedDirty;
732 final int dalvikShared = memInfo.dalvikSharedDirty;
733 final int otherShared = memInfo.otherSharedDirty;
734
735 final int nativePrivate = memInfo.nativePrivateDirty;
736 final int dalvikPrivate = memInfo.dalvikPrivateDirty;
737 final int otherPrivate = memInfo.otherPrivateDirty;
738
739 Runtime runtime = Runtime.getRuntime();
740
741 long dalvikMax = runtime.totalMemory() / 1024;
742 long dalvikFree = runtime.freeMemory() / 1024;
743 long dalvikAllocated = dalvikMax - dalvikFree;
744 long viewInstanceCount = ViewDebug.getViewInstanceCount();
745 long viewRootInstanceCount = ViewDebug.getViewRootInstanceCount();
Brian Carlstromc21550a2010-10-05 21:34:06 -0700746 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
747 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800748 int globalAssetCount = AssetManager.getGlobalAssetCount();
749 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
750 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
751 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
752 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
Brian Carlstromc9d5b312010-10-05 22:23:41 -0700753 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800754 long sqliteAllocated = SQLiteDebug.getHeapAllocatedSize() / 1024;
Vasu Noric3849202010-03-09 10:47:25 -0800755 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
Bob Leee5408332009-09-04 18:31:17 -0700756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 // Check to see if we were called by checkin server. If so, print terse format.
758 boolean doCheckinFormat = false;
759 if (args != null) {
760 for (String arg : args) {
761 if ("-c".equals(arg)) doCheckinFormat = true;
762 }
763 }
Bob Leee5408332009-09-04 18:31:17 -0700764
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800765 // For checkin, we print one long comma-separated list of values
766 if (doCheckinFormat) {
767 // NOTE: if you change anything significant below, also consider changing
768 // ACTIVITY_THREAD_CHECKIN_VERSION.
Bob Leee5408332009-09-04 18:31:17 -0700769 String processName = (mBoundApplication != null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800770 ? mBoundApplication.processName : "unknown";
Bob Leee5408332009-09-04 18:31:17 -0700771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 // Header
773 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
774 pw.print(Process.myPid()); pw.print(',');
775 pw.print(processName); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700776
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800777 // Heap info - max
778 pw.print(nativeMax); pw.print(',');
779 pw.print(dalvikMax); pw.print(',');
780 pw.print("N/A,");
781 pw.print(nativeMax + dalvikMax); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700782
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800783 // Heap info - allocated
784 pw.print(nativeAllocated); pw.print(',');
785 pw.print(dalvikAllocated); pw.print(',');
786 pw.print("N/A,");
787 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700788
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800789 // Heap info - free
790 pw.print(nativeFree); pw.print(',');
791 pw.print(dalvikFree); pw.print(',');
792 pw.print("N/A,");
793 pw.print(nativeFree + dalvikFree); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800795 // Heap info - proportional set size
796 pw.print(memInfo.nativePss); pw.print(',');
797 pw.print(memInfo.dalvikPss); pw.print(',');
798 pw.print(memInfo.otherPss); pw.print(',');
799 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700800
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800801 // Heap info - shared
Bob Leee5408332009-09-04 18:31:17 -0700802 pw.print(nativeShared); pw.print(',');
803 pw.print(dalvikShared); pw.print(',');
804 pw.print(otherShared); pw.print(',');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 pw.print(nativeShared + dalvikShared + otherShared); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 // Heap info - private
Bob Leee5408332009-09-04 18:31:17 -0700808 pw.print(nativePrivate); pw.print(',');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 pw.print(dalvikPrivate); pw.print(',');
810 pw.print(otherPrivate); pw.print(',');
811 pw.print(nativePrivate + dalvikPrivate + otherPrivate); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700812
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800813 // Object counts
814 pw.print(viewInstanceCount); pw.print(',');
815 pw.print(viewRootInstanceCount); pw.print(',');
816 pw.print(appContextInstanceCount); pw.print(',');
817 pw.print(activityInstanceCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800819 pw.print(globalAssetCount); pw.print(',');
820 pw.print(globalAssetManagerCount); pw.print(',');
821 pw.print(binderLocalObjectCount); pw.print(',');
822 pw.print(binderProxyObjectCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 pw.print(binderDeathObjectCount); pw.print(',');
825 pw.print(openSslSocketCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700826
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800827 // SQL
828 pw.print(sqliteAllocated); pw.print(',');
Vasu Noric3849202010-03-09 10:47:25 -0800829 pw.print(stats.memoryUsed / 1024); pw.print(',');
830 pw.print(stats.pageCacheOverflo / 1024); pw.print(',');
831 pw.print(stats.largestMemAlloc / 1024); pw.print(',');
832 for (int i = 0; i < stats.dbStats.size(); i++) {
833 DbStats dbStats = stats.dbStats.get(i);
834 printRow(pw, DB_INFO_FORMAT, dbStats.pageSize, dbStats.dbSize,
Vasu Nori90a367262010-04-12 12:49:09 -0700835 dbStats.lookaside, dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -0800836 pw.print(',');
837 }
Bob Leee5408332009-09-04 18:31:17 -0700838
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 return;
840 }
Bob Leee5408332009-09-04 18:31:17 -0700841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 // otherwise, show human-readable format
843 printRow(pw, HEAP_COLUMN, "", "native", "dalvik", "other", "total");
844 printRow(pw, HEAP_COLUMN, "size:", nativeMax, dalvikMax, "N/A", nativeMax + dalvikMax);
845 printRow(pw, HEAP_COLUMN, "allocated:", nativeAllocated, dalvikAllocated, "N/A",
846 nativeAllocated + dalvikAllocated);
847 printRow(pw, HEAP_COLUMN, "free:", nativeFree, dalvikFree, "N/A",
848 nativeFree + dalvikFree);
849
850 printRow(pw, HEAP_COLUMN, "(Pss):", memInfo.nativePss, memInfo.dalvikPss,
851 memInfo.otherPss, memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss);
852
853 printRow(pw, HEAP_COLUMN, "(shared dirty):", nativeShared, dalvikShared, otherShared,
854 nativeShared + dalvikShared + otherShared);
855 printRow(pw, HEAP_COLUMN, "(priv dirty):", nativePrivate, dalvikPrivate, otherPrivate,
856 nativePrivate + dalvikPrivate + otherPrivate);
857
858 pw.println(" ");
859 pw.println(" Objects");
860 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRoots:",
861 viewRootInstanceCount);
862
863 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
864 "Activities:", activityInstanceCount);
865
866 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
867 "AssetManagers:", globalAssetManagerCount);
868
869 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
870 "Proxy Binders:", binderProxyObjectCount);
871 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
872
873 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
Bob Leee5408332009-09-04 18:31:17 -0700874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 // SQLite mem info
876 pw.println(" ");
877 pw.println(" SQL");
Vasu Nori3c7131f2010-09-21 14:36:57 -0700878 printRow(pw, TWO_COUNT_COLUMNS_DB, "heap:", sqliteAllocated, "MEMORY_USED:",
Vasu Noric3849202010-03-09 10:47:25 -0800879 stats.memoryUsed / 1024);
Vasu Nori3c7131f2010-09-21 14:36:57 -0700880 printRow(pw, TWO_COUNT_COLUMNS_DB, "PAGECACHE_OVERFLOW:",
881 stats.pageCacheOverflo / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -0800882 pw.println(" ");
883 int N = stats.dbStats.size();
884 if (N > 0) {
885 pw.println(" DATABASES");
Vasu Nori3c7131f2010-09-21 14:36:57 -0700886 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
887 "Dbname");
Vasu Noric3849202010-03-09 10:47:25 -0800888 for (int i = 0; i < N; i++) {
889 DbStats dbStats = stats.dbStats.get(i);
Vasu Nori3c7131f2010-09-21 14:36:57 -0700890 printRow(pw, DB_INFO_FORMAT,
891 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
892 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
893 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
894 dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -0800895 }
896 }
Bob Leee5408332009-09-04 18:31:17 -0700897
Dianne Hackborn82e1ee92009-08-11 18:56:41 -0700898 // Asset details.
899 String assetAlloc = AssetManager.getAssetAllocations();
900 if (assetAlloc != null) {
901 pw.println(" ");
902 pw.println(" Asset Allocations");
903 pw.print(assetAlloc);
904 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905 }
906
907 private void printRow(PrintWriter pw, String format, Object...objs) {
908 pw.println(String.format(format, objs));
909 }
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800910
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -0800911 public void setCoreSettings(Bundle coreSettings) {
912 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800913 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 }
915
916 private final class H extends Handler {
917 public static final int LAUNCH_ACTIVITY = 100;
918 public static final int PAUSE_ACTIVITY = 101;
919 public static final int PAUSE_ACTIVITY_FINISHING= 102;
920 public static final int STOP_ACTIVITY_SHOW = 103;
921 public static final int STOP_ACTIVITY_HIDE = 104;
922 public static final int SHOW_WINDOW = 105;
923 public static final int HIDE_WINDOW = 106;
924 public static final int RESUME_ACTIVITY = 107;
925 public static final int SEND_RESULT = 108;
Brian Carlstromed7e0072011-03-24 13:27:57 -0700926 public static final int DESTROY_ACTIVITY = 109;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 public static final int BIND_APPLICATION = 110;
928 public static final int EXIT_APPLICATION = 111;
929 public static final int NEW_INTENT = 112;
930 public static final int RECEIVER = 113;
931 public static final int CREATE_SERVICE = 114;
932 public static final int SERVICE_ARGS = 115;
933 public static final int STOP_SERVICE = 116;
934 public static final int REQUEST_THUMBNAIL = 117;
935 public static final int CONFIGURATION_CHANGED = 118;
936 public static final int CLEAN_UP_CONTEXT = 119;
937 public static final int GC_WHEN_IDLE = 120;
938 public static final int BIND_SERVICE = 121;
939 public static final int UNBIND_SERVICE = 122;
940 public static final int DUMP_SERVICE = 123;
941 public static final int LOW_MEMORY = 124;
942 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
943 public static final int RELAUNCH_ACTIVITY = 126;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800944 public static final int PROFILER_CONTROL = 127;
Christopher Tate181fafa2009-05-14 11:12:14 -0700945 public static final int CREATE_BACKUP_AGENT = 128;
Christopher Tate5e1ab332009-09-01 20:32:49 -0700946 public static final int DESTROY_BACKUP_AGENT = 129;
947 public static final int SUICIDE = 130;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700948 public static final int REMOVE_PROVIDER = 131;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -0800949 public static final int ENABLE_JIT = 132;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700950 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700951 public static final int SCHEDULE_CRASH = 134;
Andy McFadden824c5102010-07-09 16:26:57 -0700952 public static final int DUMP_HEAP = 135;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700953 public static final int DUMP_ACTIVITY = 136;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800954 public static final int SLEEPING = 137;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800955 public static final int SET_CORE_SETTINGS = 138;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800956 String codeToString(int code) {
Dianne Hackborn287952c2010-09-22 22:34:31 -0700957 if (DEBUG_MESSAGES) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800958 switch (code) {
959 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
960 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
961 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
962 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
963 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
964 case SHOW_WINDOW: return "SHOW_WINDOW";
965 case HIDE_WINDOW: return "HIDE_WINDOW";
966 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
967 case SEND_RESULT: return "SEND_RESULT";
968 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
969 case BIND_APPLICATION: return "BIND_APPLICATION";
970 case EXIT_APPLICATION: return "EXIT_APPLICATION";
971 case NEW_INTENT: return "NEW_INTENT";
972 case RECEIVER: return "RECEIVER";
973 case CREATE_SERVICE: return "CREATE_SERVICE";
974 case SERVICE_ARGS: return "SERVICE_ARGS";
975 case STOP_SERVICE: return "STOP_SERVICE";
976 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
977 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
978 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
979 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
980 case BIND_SERVICE: return "BIND_SERVICE";
981 case UNBIND_SERVICE: return "UNBIND_SERVICE";
982 case DUMP_SERVICE: return "DUMP_SERVICE";
983 case LOW_MEMORY: return "LOW_MEMORY";
984 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
985 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800986 case PROFILER_CONTROL: return "PROFILER_CONTROL";
Christopher Tate181fafa2009-05-14 11:12:14 -0700987 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
988 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
Christopher Tate5e1ab332009-09-01 20:32:49 -0700989 case SUICIDE: return "SUICIDE";
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700990 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
Dianne Hackborn2a9094d2010-02-03 19:20:09 -0800991 case ENABLE_JIT: return "ENABLE_JIT";
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700992 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700993 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
Andy McFadden824c5102010-07-09 16:26:57 -0700994 case DUMP_HEAP: return "DUMP_HEAP";
Dianne Hackborn625ac272010-09-17 18:29:22 -0700995 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
Dianne Hackborn4eba96b2011-01-21 13:34:36 -0800996 case SLEEPING: return "SLEEPING";
Svetoslav Ganov54d068e2011-03-02 12:58:40 -0800997 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 }
999 }
1000 return "(unknown)";
1001 }
1002 public void handleMessage(Message msg) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001003 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 switch (msg.what) {
1005 case LAUNCH_ACTIVITY: {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001006 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007
1008 r.packageInfo = getPackageInfoNoCheck(
1009 r.activityInfo.applicationInfo);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001010 handleLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001011 } break;
1012 case RELAUNCH_ACTIVITY: {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001013 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08001014 handleRelaunchActivity(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 } break;
1016 case PAUSE_ACTIVITY:
1017 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
Bob Leee5408332009-09-04 18:31:17 -07001018 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001019 break;
1020 case PAUSE_ACTIVITY_FINISHING:
1021 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
1022 break;
1023 case STOP_ACTIVITY_SHOW:
1024 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
1025 break;
1026 case STOP_ACTIVITY_HIDE:
1027 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
1028 break;
1029 case SHOW_WINDOW:
1030 handleWindowVisibility((IBinder)msg.obj, true);
1031 break;
1032 case HIDE_WINDOW:
1033 handleWindowVisibility((IBinder)msg.obj, false);
1034 break;
1035 case RESUME_ACTIVITY:
1036 handleResumeActivity((IBinder)msg.obj, true,
1037 msg.arg1 != 0);
1038 break;
1039 case SEND_RESULT:
1040 handleSendResult((ResultData)msg.obj);
1041 break;
1042 case DESTROY_ACTIVITY:
1043 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1044 msg.arg2, false);
1045 break;
1046 case BIND_APPLICATION:
1047 AppBindData data = (AppBindData)msg.obj;
1048 handleBindApplication(data);
1049 break;
1050 case EXIT_APPLICATION:
1051 if (mInitialApplication != null) {
1052 mInitialApplication.onTerminate();
1053 }
1054 Looper.myLooper().quit();
1055 break;
1056 case NEW_INTENT:
1057 handleNewIntent((NewIntentData)msg.obj);
1058 break;
1059 case RECEIVER:
1060 handleReceiver((ReceiverData)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001061 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001062 break;
1063 case CREATE_SERVICE:
1064 handleCreateService((CreateServiceData)msg.obj);
1065 break;
1066 case BIND_SERVICE:
1067 handleBindService((BindServiceData)msg.obj);
1068 break;
1069 case UNBIND_SERVICE:
1070 handleUnbindService((BindServiceData)msg.obj);
1071 break;
1072 case SERVICE_ARGS:
1073 handleServiceArgs((ServiceArgsData)msg.obj);
1074 break;
1075 case STOP_SERVICE:
1076 handleStopService((IBinder)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001077 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001078 break;
1079 case REQUEST_THUMBNAIL:
1080 handleRequestThumbnail((IBinder)msg.obj);
1081 break;
1082 case CONFIGURATION_CHANGED:
1083 handleConfigurationChanged((Configuration)msg.obj);
1084 break;
1085 case CLEAN_UP_CONTEXT:
1086 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1087 cci.context.performFinalCleanup(cci.who, cci.what);
1088 break;
1089 case GC_WHEN_IDLE:
1090 scheduleGcIdler();
1091 break;
1092 case DUMP_SERVICE:
Dianne Hackborn625ac272010-09-17 18:29:22 -07001093 handleDumpService((DumpComponentInfo)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 break;
1095 case LOW_MEMORY:
1096 handleLowMemory();
1097 break;
1098 case ACTIVITY_CONFIGURATION_CHANGED:
1099 handleActivityConfigurationChanged((IBinder)msg.obj);
1100 break;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001101 case PROFILER_CONTROL:
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07001102 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001103 break;
Christopher Tate181fafa2009-05-14 11:12:14 -07001104 case CREATE_BACKUP_AGENT:
1105 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1106 break;
1107 case DESTROY_BACKUP_AGENT:
1108 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1109 break;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001110 case SUICIDE:
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001111 Process.killProcess(Process.myPid());
1112 break;
1113 case REMOVE_PROVIDER:
1114 completeRemoveProvider((IContentProvider)msg.obj);
Christopher Tate5e1ab332009-09-01 20:32:49 -07001115 break;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001116 case ENABLE_JIT:
1117 ensureJitEnabled();
1118 break;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001119 case DISPATCH_PACKAGE_BROADCAST:
1120 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1121 break;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001122 case SCHEDULE_CRASH:
1123 throw new RemoteServiceException((String)msg.obj);
Andy McFadden824c5102010-07-09 16:26:57 -07001124 case DUMP_HEAP:
1125 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1126 break;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001127 case DUMP_ACTIVITY:
1128 handleDumpActivity((DumpComponentInfo)msg.obj);
1129 break;
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08001130 case SLEEPING:
1131 handleSleeping((IBinder)msg.obj, msg.arg1 != 0);
1132 break;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08001133 case SET_CORE_SETTINGS:
1134 handleSetCoreSettings((Bundle) msg.obj);
1135 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07001137 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001138 }
Bob Leee5408332009-09-04 18:31:17 -07001139
Brian Carlstromed7e0072011-03-24 13:27:57 -07001140 private void maybeSnapshot() {
1141 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) {
Sen Hubde75702010-05-28 01:54:03 -07001142 // convert the *private* ActivityThread.PackageInfo to *public* known
1143 // android.content.pm.PackageInfo
1144 String packageName = mBoundApplication.info.mPackageName;
1145 android.content.pm.PackageInfo packageInfo = null;
1146 try {
1147 Context context = getSystemContext();
1148 if(context == null) {
1149 Log.e(TAG, "cannot get a valid context");
1150 return;
1151 }
1152 PackageManager pm = context.getPackageManager();
1153 if(pm == null) {
1154 Log.e(TAG, "cannot get a valid PackageManager");
1155 return;
1156 }
1157 packageInfo = pm.getPackageInfo(
1158 packageName, PackageManager.GET_ACTIVITIES);
1159 } catch (NameNotFoundException e) {
1160 Log.e(TAG, "cannot get package info for " + packageName, e);
1161 }
1162 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
Bob Leee5408332009-09-04 18:31:17 -07001163 }
1164 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001165 }
1166
1167 private final class Idler implements MessageQueue.IdleHandler {
1168 public final boolean queueIdle() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001169 ActivityClientRecord a = mNewActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 if (a != null) {
1171 mNewActivities = null;
1172 IActivityManager am = ActivityManagerNative.getDefault();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001173 ActivityClientRecord prev;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001174 do {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001175 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001176 TAG, "Reporting idle of " + a +
1177 " finished=" +
1178 (a.activity != null ? a.activity.mFinished : false));
1179 if (a.activity != null && !a.activity.mFinished) {
1180 try {
Dianne Hackborne88846e2009-09-30 21:34:25 -07001181 am.activityIdle(a.token, a.createdConfig);
1182 a.createdConfig = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001183 } catch (RemoteException ex) {
1184 }
1185 }
1186 prev = a;
1187 a = a.nextIdle;
1188 prev.nextIdle = null;
1189 } while (a != null);
1190 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001191 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 return false;
1193 }
1194 }
1195
1196 final class GcIdler implements MessageQueue.IdleHandler {
1197 public final boolean queueIdle() {
1198 doGcIfNeeded();
1199 return false;
1200 }
1201 }
1202
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001203 private final static class ResourcesKey {
1204 final private String mResDir;
1205 final private float mScale;
1206 final private int mHash;
Bob Leee5408332009-09-04 18:31:17 -07001207
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001208 ResourcesKey(String resDir, float scale) {
1209 mResDir = resDir;
1210 mScale = scale;
1211 mHash = mResDir.hashCode() << 2 + (int) (mScale * 2);
1212 }
Bob Leee5408332009-09-04 18:31:17 -07001213
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001214 @Override
1215 public int hashCode() {
1216 return mHash;
1217 }
1218
1219 @Override
1220 public boolean equals(Object obj) {
1221 if (!(obj instanceof ResourcesKey)) {
1222 return false;
1223 }
1224 ResourcesKey peer = (ResourcesKey) obj;
1225 return mResDir.equals(peer.mResDir) && mScale == peer.mScale;
1226 }
1227 }
1228
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001229 public static final ActivityThread currentActivityThread() {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07001230 return sThreadLocal.get();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001233 public static final String currentPackageName() {
1234 ActivityThread am = currentActivityThread();
1235 return (am != null && am.mBoundApplication != null)
1236 ? am.mBoundApplication.processName : null;
1237 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001238
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001239 public static final Application currentApplication() {
1240 ActivityThread am = currentActivityThread();
1241 return am != null ? am.mInitialApplication : null;
1242 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001244 public static IPackageManager getPackageManager() {
1245 if (sPackageManager != null) {
1246 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1247 return sPackageManager;
1248 }
1249 IBinder b = ServiceManager.getService("package");
1250 //Slog.v("PackageManager", "default service binder = " + b);
1251 sPackageManager = IPackageManager.Stub.asInterface(b);
1252 //Slog.v("PackageManager", "default service = " + sPackageManager);
1253 return sPackageManager;
1254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001256 DisplayMetrics getDisplayMetricsLocked(boolean forceUpdate) {
1257 if (mDisplayMetrics != null && !forceUpdate) {
1258 return mDisplayMetrics;
1259 }
1260 if (mDisplay == null) {
1261 WindowManager wm = WindowManagerImpl.getDefault();
1262 mDisplay = wm.getDefaultDisplay();
1263 }
1264 DisplayMetrics metrics = mDisplayMetrics = new DisplayMetrics();
1265 mDisplay.getMetrics(metrics);
1266 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1267 // + metrics.heightPixels + " den=" + metrics.density
1268 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
1269 return metrics;
1270 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001272 /**
1273 * Creates the top level Resources for applications with the given compatibility info.
1274 *
1275 * @param resDir the resource directory.
1276 * @param compInfo the compability info. It will use the default compatibility info when it's
1277 * null.
1278 */
1279 Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
1280 ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
1281 Resources r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001282 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001283 // Resources is app scale dependent.
1284 if (false) {
1285 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1286 + compInfo.applicationScale);
1287 }
1288 WeakReference<Resources> wr = mActiveResources.get(key);
1289 r = wr != null ? wr.get() : null;
1290 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1291 if (r != null && r.getAssets().isUpToDate()) {
1292 if (false) {
1293 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1294 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1295 }
1296 return r;
1297 }
1298 }
1299
1300 //if (r != null) {
1301 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1302 // + r + " " + resDir);
1303 //}
1304
1305 AssetManager assets = new AssetManager();
1306 if (assets.addAssetPath(resDir) == 0) {
1307 return null;
1308 }
1309
1310 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
1311 DisplayMetrics metrics = getDisplayMetricsLocked(false);
1312 r = new Resources(assets, metrics, getConfiguration(), compInfo);
1313 if (false) {
1314 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1315 + r.getConfiguration() + " appScale="
1316 + r.getCompatibilityInfo().applicationScale);
1317 }
1318
1319 synchronized (mPackages) {
1320 WeakReference<Resources> wr = mActiveResources.get(key);
1321 Resources existing = wr != null ? wr.get() : null;
1322 if (existing != null && existing.getAssets().isUpToDate()) {
1323 // Someone else already created the resources while we were
1324 // unlocked; go ahead and use theirs.
1325 r.getAssets().close();
1326 return existing;
1327 }
1328
1329 // XXX need to remove entries when weak references go away
1330 mActiveResources.put(key, new WeakReference<Resources>(r));
1331 return r;
1332 }
1333 }
1334
1335 /**
1336 * Creates the top level resources for the given package.
1337 */
1338 Resources getTopLevelResources(String resDir, LoadedApk pkgInfo) {
1339 return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo);
1340 }
1341
1342 final Handler getHandler() {
1343 return mH;
1344 }
1345
1346 public final LoadedApk getPackageInfo(String packageName, int flags) {
1347 synchronized (mPackages) {
1348 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001349 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1350 ref = mPackages.get(packageName);
1351 } else {
1352 ref = mResourcePackages.get(packageName);
1353 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001354 LoadedApk packageInfo = ref != null ? ref.get() : null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001355 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001356 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1357 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 if (packageInfo != null && (packageInfo.mResources == null
1359 || packageInfo.mResources.getAssets().isUpToDate())) {
1360 if (packageInfo.isSecurityViolation()
1361 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1362 throw new SecurityException(
1363 "Requesting code from " + packageName
1364 + " to be run in process "
1365 + mBoundApplication.processName
1366 + "/" + mBoundApplication.appInfo.uid);
1367 }
1368 return packageInfo;
1369 }
1370 }
1371
1372 ApplicationInfo ai = null;
1373 try {
1374 ai = getPackageManager().getApplicationInfo(packageName,
1375 PackageManager.GET_SHARED_LIBRARY_FILES);
1376 } catch (RemoteException e) {
1377 }
1378
1379 if (ai != null) {
1380 return getPackageInfo(ai, flags);
1381 }
1382
1383 return null;
1384 }
1385
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001386 public final LoadedApk getPackageInfo(ApplicationInfo ai, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1388 boolean securityViolation = includeCode && ai.uid != 0
1389 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1390 ? ai.uid != mBoundApplication.appInfo.uid : true);
1391 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1392 |Context.CONTEXT_IGNORE_SECURITY))
1393 == Context.CONTEXT_INCLUDE_CODE) {
1394 if (securityViolation) {
1395 String msg = "Requesting code from " + ai.packageName
1396 + " (with uid " + ai.uid + ")";
1397 if (mBoundApplication != null) {
1398 msg = msg + " to be run in process "
1399 + mBoundApplication.processName + " (with uid "
1400 + mBoundApplication.appInfo.uid + ")";
1401 }
1402 throw new SecurityException(msg);
1403 }
1404 }
1405 return getPackageInfo(ai, null, securityViolation, includeCode);
1406 }
1407
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001408 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001409 return getPackageInfo(ai, null, false, true);
1410 }
1411
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001412 private final LoadedApk getPackageInfo(ApplicationInfo aInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1414 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001415 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001416 if (includeCode) {
1417 ref = mPackages.get(aInfo.packageName);
1418 } else {
1419 ref = mResourcePackages.get(aInfo.packageName);
1420 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001421 LoadedApk packageInfo = ref != null ? ref.get() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001422 if (packageInfo == null || (packageInfo.mResources != null
1423 && !packageInfo.mResources.getAssets().isUpToDate())) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001424 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 : "Loading resource-only package ") + aInfo.packageName
1426 + " (in " + (mBoundApplication != null
1427 ? mBoundApplication.processName : null)
1428 + ")");
1429 packageInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001430 new LoadedApk(this, aInfo, this, baseLoader,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431 securityViolation, includeCode &&
1432 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1433 if (includeCode) {
1434 mPackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001435 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 } else {
1437 mResourcePackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001438 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 }
1440 }
1441 return packageInfo;
1442 }
1443 }
1444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001445 ActivityThread() {
1446 }
1447
1448 public ApplicationThread getApplicationThread()
1449 {
1450 return mAppThread;
1451 }
1452
1453 public Instrumentation getInstrumentation()
1454 {
1455 return mInstrumentation;
1456 }
1457
1458 public Configuration getConfiguration() {
1459 return mConfiguration;
1460 }
1461
1462 public boolean isProfiling() {
1463 return mBoundApplication != null && mBoundApplication.profileFile != null;
1464 }
1465
1466 public String getProfileFilePath() {
1467 return mBoundApplication.profileFile;
1468 }
1469
1470 public Looper getLooper() {
1471 return mLooper;
1472 }
1473
1474 public Application getApplication() {
1475 return mInitialApplication;
1476 }
Bob Leee5408332009-09-04 18:31:17 -07001477
Dianne Hackbornd97c7ad2009-06-19 11:37:35 -07001478 public String getProcessName() {
1479 return mBoundApplication.processName;
1480 }
Bob Leee5408332009-09-04 18:31:17 -07001481
Dianne Hackborn21556372010-02-04 16:34:40 -08001482 public ContextImpl getSystemContext() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 synchronized (this) {
1484 if (mSystemContext == null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001485 ContextImpl context =
1486 ContextImpl.createSystemContext(this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001487 LoadedApk info = new LoadedApk(this, "android", context, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001488 context.init(info, null, this);
1489 context.getResources().updateConfiguration(
1490 getConfiguration(), getDisplayMetricsLocked(false));
1491 mSystemContext = context;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001492 //Slog.i(TAG, "Created system resources " + context.getResources()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001493 // + ": " + context.getResources().getConfiguration());
1494 }
1495 }
1496 return mSystemContext;
1497 }
1498
Mike Cleron432b7132009-09-24 15:28:29 -07001499 public void installSystemApplicationInfo(ApplicationInfo info) {
1500 synchronized (this) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001501 ContextImpl context = getSystemContext();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001502 context.init(new LoadedApk(this, "android", context, info), null, this);
Mike Cleron432b7132009-09-24 15:28:29 -07001503 }
1504 }
1505
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001506 void ensureJitEnabled() {
1507 if (!mJitEnabled) {
1508 mJitEnabled = true;
1509 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1510 }
1511 }
1512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001513 void scheduleGcIdler() {
1514 if (!mGcIdlerScheduled) {
1515 mGcIdlerScheduled = true;
1516 Looper.myQueue().addIdleHandler(mGcIdler);
1517 }
1518 mH.removeMessages(H.GC_WHEN_IDLE);
1519 }
1520
1521 void unscheduleGcIdler() {
1522 if (mGcIdlerScheduled) {
1523 mGcIdlerScheduled = false;
1524 Looper.myQueue().removeIdleHandler(mGcIdler);
1525 }
1526 mH.removeMessages(H.GC_WHEN_IDLE);
1527 }
1528
1529 void doGcIfNeeded() {
1530 mGcIdlerScheduled = false;
1531 final long now = SystemClock.uptimeMillis();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001532 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 // + "m now=" + now);
1534 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001535 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001536 BinderInternal.forceGc("bg");
1537 }
1538 }
1539
Jeff Hamilton52d32032011-01-08 15:31:26 -06001540 public void registerOnActivityPausedListener(Activity activity,
1541 OnActivityPausedListener listener) {
1542 synchronized (mOnPauseListeners) {
1543 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1544 if (list == null) {
1545 list = new ArrayList<OnActivityPausedListener>();
1546 mOnPauseListeners.put(activity, list);
1547 }
1548 list.add(listener);
1549 }
1550 }
1551
Jeff Hamiltonce3224c2011-01-17 11:05:03 -08001552 public void unregisterOnActivityPausedListener(Activity activity,
1553 OnActivityPausedListener listener) {
1554 synchronized (mOnPauseListeners) {
1555 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity);
1556 if (list != null) {
1557 list.remove(listener);
1558 }
1559 }
1560 }
1561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 public final ActivityInfo resolveActivityInfo(Intent intent) {
1563 ActivityInfo aInfo = intent.resolveActivityInfo(
1564 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
1565 if (aInfo == null) {
1566 // Throw an exception.
1567 Instrumentation.checkStartActivityResult(
1568 IActivityManager.START_CLASS_NOT_FOUND, intent);
1569 }
1570 return aInfo;
1571 }
Bob Leee5408332009-09-04 18:31:17 -07001572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001573 public final Activity startActivityNow(Activity parent, String id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001574 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001575 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001576 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001578 r.ident = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 r.intent = intent;
1580 r.state = state;
1581 r.parent = parent;
1582 r.embeddedID = id;
1583 r.activityInfo = activityInfo;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001584 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001585 if (localLOGV) {
1586 ComponentName compname = intent.getComponent();
1587 String name;
1588 if (compname != null) {
1589 name = compname.toShortString();
1590 } else {
1591 name = "(Intent " + intent + ").getComponent() returned null";
1592 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001593 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001594 + ", comp=" + name
1595 + ", token=" + token);
1596 }
Christopher Tateb70f3df2009-04-07 16:07:59 -07001597 return performLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 }
1599
1600 public final Activity getActivity(IBinder token) {
1601 return mActivities.get(token).activity;
1602 }
1603
1604 public final void sendActivityResult(
1605 IBinder token, String id, int requestCode,
1606 int resultCode, Intent data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001607 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
Chris Tate8a7dc172009-03-24 20:11:42 -07001608 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
1610 list.add(new ResultInfo(id, requestCode, resultCode, data));
1611 mAppThread.scheduleSendResult(token, list);
1612 }
1613
1614 // if the thread hasn't started yet, we don't have the handler, so just
1615 // save the messages until we're ready.
1616 private final void queueOrSendMessage(int what, Object obj) {
1617 queueOrSendMessage(what, obj, 0, 0);
1618 }
1619
1620 private final void queueOrSendMessage(int what, Object obj, int arg1) {
1621 queueOrSendMessage(what, obj, arg1, 0);
1622 }
1623
1624 private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
1625 synchronized (this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001626 if (DEBUG_MESSAGES) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001627 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
1628 + ": " + arg1 + " / " + obj);
1629 Message msg = Message.obtain();
1630 msg.what = what;
1631 msg.obj = obj;
1632 msg.arg1 = arg1;
1633 msg.arg2 = arg2;
1634 mH.sendMessage(msg);
1635 }
1636 }
1637
Dianne Hackborn21556372010-02-04 16:34:40 -08001638 final void scheduleContextCleanup(ContextImpl context, String who,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001639 String what) {
1640 ContextCleanupInfo cci = new ContextCleanupInfo();
1641 cci.context = context;
1642 cci.who = who;
1643 cci.what = what;
1644 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
1645 }
1646
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001647 private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001648 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
1649
1650 ActivityInfo aInfo = r.activityInfo;
1651 if (r.packageInfo == null) {
1652 r.packageInfo = getPackageInfo(aInfo.applicationInfo,
1653 Context.CONTEXT_INCLUDE_CODE);
1654 }
Bob Leee5408332009-09-04 18:31:17 -07001655
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001656 ComponentName component = r.intent.getComponent();
1657 if (component == null) {
1658 component = r.intent.resolveActivity(
1659 mInitialApplication.getPackageManager());
1660 r.intent.setComponent(component);
1661 }
1662
1663 if (r.activityInfo.targetActivity != null) {
1664 component = new ComponentName(r.activityInfo.packageName,
1665 r.activityInfo.targetActivity);
1666 }
1667
1668 Activity activity = null;
1669 try {
1670 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
1671 activity = mInstrumentation.newActivity(
1672 cl, component.getClassName(), r.intent);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08001673 StrictMode.incrementExpectedActivityCount(activity.getClass());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001674 r.intent.setExtrasClassLoader(cl);
1675 if (r.state != null) {
1676 r.state.setClassLoader(cl);
1677 }
1678 } catch (Exception e) {
1679 if (!mInstrumentation.onException(activity, e)) {
1680 throw new RuntimeException(
1681 "Unable to instantiate activity " + component
1682 + ": " + e.toString(), e);
1683 }
1684 }
1685
1686 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08001687 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07001688
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001689 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
1690 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001691 TAG, r + ": app=" + app
1692 + ", appName=" + app.getPackageName()
1693 + ", pkg=" + r.packageInfo.getPackageName()
1694 + ", comp=" + r.intent.getComponent().toShortString()
1695 + ", dir=" + r.packageInfo.getAppDir());
1696
1697 if (activity != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001698 ContextImpl appContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 appContext.init(r.packageInfo, r.token, this);
1700 appContext.setOuterContext(activity);
1701 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
1702 Configuration config = new Configuration(mConfiguration);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001703 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07001704 + r.activityInfo.name + " with config " + config);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001705 activity.attach(appContext, this, getInstrumentation(), r.token,
1706 r.ident, app, r.intent, r.activityInfo, title, r.parent,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001707 r.embeddedID, r.lastNonConfigurationInstances, config);
Bob Leee5408332009-09-04 18:31:17 -07001708
Christopher Tateb70f3df2009-04-07 16:07:59 -07001709 if (customIntent != null) {
1710 activity.mIntent = customIntent;
1711 }
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001712 r.lastNonConfigurationInstances = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001713 activity.mStartedActivity = false;
1714 int theme = r.activityInfo.getThemeResource();
1715 if (theme != 0) {
1716 activity.setTheme(theme);
1717 }
1718
1719 activity.mCalled = false;
1720 mInstrumentation.callActivityOnCreate(activity, r.state);
1721 if (!activity.mCalled) {
1722 throw new SuperNotCalledException(
1723 "Activity " + r.intent.getComponent().toShortString() +
1724 " did not call through to super.onCreate()");
1725 }
1726 r.activity = activity;
1727 r.stopped = true;
1728 if (!r.activity.mFinished) {
1729 activity.performStart();
1730 r.stopped = false;
1731 }
1732 if (!r.activity.mFinished) {
1733 if (r.state != null) {
1734 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
1735 }
1736 }
1737 if (!r.activity.mFinished) {
1738 activity.mCalled = false;
1739 mInstrumentation.callActivityOnPostCreate(activity, r.state);
1740 if (!activity.mCalled) {
1741 throw new SuperNotCalledException(
1742 "Activity " + r.intent.getComponent().toShortString() +
1743 " did not call through to super.onPostCreate()");
1744 }
1745 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001746 }
1747 r.paused = true;
1748
1749 mActivities.put(r.token, r);
1750
1751 } catch (SuperNotCalledException e) {
1752 throw e;
1753
1754 } catch (Exception e) {
1755 if (!mInstrumentation.onException(activity, e)) {
1756 throw new RuntimeException(
1757 "Unable to start activity " + component
1758 + ": " + e.toString(), e);
1759 }
1760 }
1761
1762 return activity;
1763 }
1764
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001765 private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001766 // If we are getting ready to gc after going to the background, well
1767 // we are back active so skip it.
1768 unscheduleGcIdler();
1769
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001770 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001771 TAG, "Handling launch of " + r);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001772 Activity a = performLaunchActivity(r, customIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001773
1774 if (a != null) {
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08001775 r.createdConfig = new Configuration(mConfiguration);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001776 Bundle oldState = r.state;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777 handleResumeActivity(r.token, false, r.isForward);
1778
1779 if (!r.activity.mFinished && r.startsNotResumed) {
1780 // The activity manager actually wants this one to start out
1781 // paused, because it needs to be visible but isn't in the
1782 // foreground. We accomplish this by going through the
1783 // normal startup (because activities expect to go through
1784 // onResume() the first time they run, before their window
1785 // is displayed), and then pausing it. However, in this case
1786 // we do -not- need to do the full pause cycle (of freezing
1787 // and such) because the activity manager assumes it can just
1788 // retain the current state it has.
1789 try {
1790 r.activity.mCalled = false;
1791 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001792 // We need to keep around the original state, in case
1793 // we need to be created again.
1794 r.state = oldState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001795 if (!r.activity.mCalled) {
1796 throw new SuperNotCalledException(
1797 "Activity " + r.intent.getComponent().toShortString() +
1798 " did not call through to super.onPause()");
1799 }
1800
1801 } catch (SuperNotCalledException e) {
1802 throw e;
1803
1804 } catch (Exception e) {
1805 if (!mInstrumentation.onException(r.activity, e)) {
1806 throw new RuntimeException(
1807 "Unable to pause activity "
1808 + r.intent.getComponent().toShortString()
1809 + ": " + e.toString(), e);
1810 }
1811 }
1812 r.paused = true;
1813 }
1814 } else {
1815 // If there was an error, for any reason, tell the activity
1816 // manager to stop us.
1817 try {
1818 ActivityManagerNative.getDefault()
1819 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
1820 } catch (RemoteException ex) {
1821 }
1822 }
1823 }
1824
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001825 private final void deliverNewIntents(ActivityClientRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001826 List<Intent> intents) {
1827 final int N = intents.size();
1828 for (int i=0; i<N; i++) {
1829 Intent intent = intents.get(i);
1830 intent.setExtrasClassLoader(r.activity.getClassLoader());
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07001831 r.activity.mFragments.noteStateNotSaved();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
1833 }
1834 }
1835
1836 public final void performNewIntents(IBinder token,
1837 List<Intent> intents) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001838 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 if (r != null) {
1840 final boolean resumed = !r.paused;
1841 if (resumed) {
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07001842 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001843 mInstrumentation.callActivityOnPause(r.activity);
1844 }
1845 deliverNewIntents(r, intents);
1846 if (resumed) {
1847 mInstrumentation.callActivityOnResume(r.activity);
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07001848 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001849 }
1850 }
1851 }
Bob Leee5408332009-09-04 18:31:17 -07001852
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001853 private final void handleNewIntent(NewIntentData data) {
1854 performNewIntents(data.token, data.intents);
1855 }
1856
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07001857 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
1858
1859 /**
1860 * Return the Intent that's currently being handled by a
1861 * BroadcastReceiver on this thread, or null if none.
1862 * @hide
1863 */
1864 public static Intent getIntentBeingBroadcast() {
1865 return sCurrentBroadcastIntent.get();
1866 }
1867
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001868 private final void handleReceiver(ReceiverData data) {
1869 // If we are getting ready to gc after going to the background, well
1870 // we are back active so skip it.
1871 unscheduleGcIdler();
1872
1873 String component = data.intent.getComponent().getClassName();
1874
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001875 LoadedApk packageInfo = getPackageInfoNoCheck(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001876 data.info.applicationInfo);
1877
1878 IActivityManager mgr = ActivityManagerNative.getDefault();
1879
1880 BroadcastReceiver receiver = null;
1881 try {
1882 java.lang.ClassLoader cl = packageInfo.getClassLoader();
1883 data.intent.setExtrasClassLoader(cl);
Dianne Hackborne829fef2010-10-26 17:44:01 -07001884 data.setExtrasClassLoader(cl);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001885 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
1886 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001887 if (DEBUG_BROADCAST) Slog.i(TAG,
1888 "Finishing failed broadcast to " + data.intent.getComponent());
1889 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001890 throw new RuntimeException(
1891 "Unable to instantiate receiver " + component
1892 + ": " + e.toString(), e);
1893 }
1894
1895 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08001896 Application app = packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07001897
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001898 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001899 TAG, "Performing receive of " + data.intent
1900 + ": app=" + app
1901 + ", appName=" + app.getPackageName()
1902 + ", pkg=" + packageInfo.getPackageName()
1903 + ", comp=" + data.intent.getComponent().toShortString()
1904 + ", dir=" + packageInfo.getAppDir());
1905
Dianne Hackborn21556372010-02-04 16:34:40 -08001906 ContextImpl context = (ContextImpl)app.getBaseContext();
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07001907 sCurrentBroadcastIntent.set(data.intent);
Dianne Hackborne829fef2010-10-26 17:44:01 -07001908 receiver.setPendingResult(data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001909 receiver.onReceive(context.getReceiverRestrictedContext(),
1910 data.intent);
1911 } catch (Exception e) {
Dianne Hackborne829fef2010-10-26 17:44:01 -07001912 if (DEBUG_BROADCAST) Slog.i(TAG,
1913 "Finishing failed broadcast to " + data.intent.getComponent());
1914 data.sendFinished(mgr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001915 if (!mInstrumentation.onException(receiver, e)) {
1916 throw new RuntimeException(
1917 "Unable to start receiver " + component
1918 + ": " + e.toString(), e);
1919 }
Brad Fitzpatrickbfb19192010-10-29 15:25:44 -07001920 } finally {
1921 sCurrentBroadcastIntent.set(null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001922 }
1923
Dianne Hackborne829fef2010-10-26 17:44:01 -07001924 if (receiver.getPendingResult() != null) {
1925 data.finish();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001926 }
1927 }
1928
Christopher Tate181fafa2009-05-14 11:12:14 -07001929 // Instantiate a BackupAgent and tell it that it's alive
1930 private final void handleCreateBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001931 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07001932
1933 // no longer idle; we have backup work to do
1934 unscheduleGcIdler();
1935
1936 // instantiate the BackupAgent class named in the manifest
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001937 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07001938 String packageName = packageInfo.mPackageName;
1939 if (mBackupAgents.get(packageName) != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001940 Slog.d(TAG, "BackupAgent " + " for " + packageName
Christopher Tate181fafa2009-05-14 11:12:14 -07001941 + " already exists");
1942 return;
1943 }
Bob Leee5408332009-09-04 18:31:17 -07001944
Christopher Tate181fafa2009-05-14 11:12:14 -07001945 BackupAgent agent = null;
1946 String classname = data.appInfo.backupAgentName;
1947 if (classname == null) {
1948 if (data.backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08001949 Slog.e(TAG, "Attempted incremental backup but no defined agent for "
Christopher Tate181fafa2009-05-14 11:12:14 -07001950 + packageName);
1951 return;
1952 }
1953 classname = "android.app.FullBackupAgent";
1954 }
1955 try {
Christopher Tated1475e02009-07-09 15:36:17 -07001956 IBinder binder = null;
1957 try {
1958 java.lang.ClassLoader cl = packageInfo.getClassLoader();
1959 agent = (BackupAgent) cl.loadClass(data.appInfo.backupAgentName).newInstance();
1960
1961 // set up the agent's context
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001962 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing BackupAgent "
Christopher Tated1475e02009-07-09 15:36:17 -07001963 + data.appInfo.backupAgentName);
1964
Dianne Hackborn21556372010-02-04 16:34:40 -08001965 ContextImpl context = new ContextImpl();
Christopher Tated1475e02009-07-09 15:36:17 -07001966 context.init(packageInfo, null, this);
1967 context.setOuterContext(agent);
1968 agent.attach(context);
1969
1970 agent.onCreate();
1971 binder = agent.onBind();
1972 mBackupAgents.put(packageName, agent);
1973 } catch (Exception e) {
1974 // If this is during restore, fail silently; otherwise go
1975 // ahead and let the user see the crash.
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08001976 Slog.e(TAG, "Agent threw during creation: " + e);
Christopher Tated1475e02009-07-09 15:36:17 -07001977 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE) {
1978 throw e;
1979 }
1980 // falling through with 'binder' still null
1981 }
Christopher Tate181fafa2009-05-14 11:12:14 -07001982
1983 // tell the OS that we're live now
Christopher Tate181fafa2009-05-14 11:12:14 -07001984 try {
1985 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
1986 } catch (RemoteException e) {
1987 // nothing to do.
1988 }
Christopher Tate181fafa2009-05-14 11:12:14 -07001989 } catch (Exception e) {
1990 throw new RuntimeException("Unable to create BackupAgent "
1991 + data.appInfo.backupAgentName + ": " + e.toString(), e);
1992 }
1993 }
1994
1995 // Tear down a BackupAgent
1996 private final void handleDestroyBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001997 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
Bob Leee5408332009-09-04 18:31:17 -07001998
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001999 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002000 String packageName = packageInfo.mPackageName;
2001 BackupAgent agent = mBackupAgents.get(packageName);
2002 if (agent != null) {
2003 try {
2004 agent.onDestroy();
2005 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002006 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07002007 e.printStackTrace();
2008 }
2009 mBackupAgents.remove(packageName);
2010 } else {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002011 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07002012 }
2013 }
2014
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 private final void handleCreateService(CreateServiceData data) {
2016 // If we are getting ready to gc after going to the background, well
2017 // we are back active so skip it.
2018 unscheduleGcIdler();
2019
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002020 LoadedApk packageInfo = getPackageInfoNoCheck(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002021 data.info.applicationInfo);
2022 Service service = null;
2023 try {
2024 java.lang.ClassLoader cl = packageInfo.getClassLoader();
2025 service = (Service) cl.loadClass(data.info.name).newInstance();
2026 } catch (Exception e) {
2027 if (!mInstrumentation.onException(service, e)) {
2028 throw new RuntimeException(
2029 "Unable to instantiate service " + data.info.name
2030 + ": " + e.toString(), e);
2031 }
2032 }
2033
2034 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002035 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002036
Dianne Hackborn21556372010-02-04 16:34:40 -08002037 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002038 context.init(packageInfo, null, this);
2039
Dianne Hackborn0be1f782009-11-09 12:30:12 -08002040 Application app = packageInfo.makeApplication(false, mInstrumentation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002041 context.setOuterContext(service);
2042 service.attach(context, this, data.info.name, data.token, app,
2043 ActivityManagerNative.getDefault());
2044 service.onCreate();
2045 mServices.put(data.token, service);
2046 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002047 ActivityManagerNative.getDefault().serviceDoneExecuting(
2048 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002049 } catch (RemoteException e) {
2050 // nothing to do.
2051 }
2052 } catch (Exception e) {
2053 if (!mInstrumentation.onException(service, e)) {
2054 throw new RuntimeException(
2055 "Unable to create service " + data.info.name
2056 + ": " + e.toString(), e);
2057 }
2058 }
2059 }
2060
2061 private final void handleBindService(BindServiceData data) {
2062 Service s = mServices.get(data.token);
2063 if (s != null) {
2064 try {
2065 data.intent.setExtrasClassLoader(s.getClassLoader());
2066 try {
2067 if (!data.rebind) {
2068 IBinder binder = s.onBind(data.intent);
2069 ActivityManagerNative.getDefault().publishService(
2070 data.token, data.intent, binder);
2071 } else {
2072 s.onRebind(data.intent);
2073 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002074 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002075 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002076 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 } catch (RemoteException ex) {
2078 }
2079 } catch (Exception e) {
2080 if (!mInstrumentation.onException(s, e)) {
2081 throw new RuntimeException(
2082 "Unable to bind to service " + s
2083 + " with " + data.intent + ": " + e.toString(), e);
2084 }
2085 }
2086 }
2087 }
2088
2089 private final void handleUnbindService(BindServiceData data) {
2090 Service s = mServices.get(data.token);
2091 if (s != null) {
2092 try {
2093 data.intent.setExtrasClassLoader(s.getClassLoader());
2094 boolean doRebind = s.onUnbind(data.intent);
2095 try {
2096 if (doRebind) {
2097 ActivityManagerNative.getDefault().unbindFinished(
2098 data.token, data.intent, doRebind);
2099 } else {
2100 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002101 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 }
2103 } catch (RemoteException ex) {
2104 }
2105 } catch (Exception e) {
2106 if (!mInstrumentation.onException(s, e)) {
2107 throw new RuntimeException(
2108 "Unable to unbind to service " + s
2109 + " with " + data.intent + ": " + e.toString(), e);
2110 }
2111 }
2112 }
2113 }
2114
Dianne Hackborn625ac272010-09-17 18:29:22 -07002115 private void handleDumpService(DumpComponentInfo info) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 try {
Dianne Hackborn625ac272010-09-17 18:29:22 -07002117 Service s = mServices.get(info.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 if (s != null) {
2119 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd));
2120 s.dump(info.fd, pw, info.args);
2121 pw.close();
2122 }
2123 } finally {
2124 synchronized (info) {
2125 info.dumped = true;
2126 info.notifyAll();
2127 }
2128 }
2129 }
2130
Dianne Hackborn625ac272010-09-17 18:29:22 -07002131 private void handleDumpActivity(DumpComponentInfo info) {
2132 try {
2133 ActivityClientRecord r = mActivities.get(info.token);
2134 if (r != null && r.activity != null) {
2135 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd));
Dianne Hackborn30d71892010-12-11 10:37:55 -08002136 r.activity.dump(info.prefix, info.fd, pw, info.args);
Dianne Hackborn625ac272010-09-17 18:29:22 -07002137 pw.close();
2138 }
2139 } finally {
2140 synchronized (info) {
2141 info.dumped = true;
2142 info.notifyAll();
2143 }
2144 }
2145 }
2146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002147 private final void handleServiceArgs(ServiceArgsData data) {
2148 Service s = mServices.get(data.token);
2149 if (s != null) {
2150 try {
2151 if (data.args != null) {
2152 data.args.setExtrasClassLoader(s.getClassLoader());
2153 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002154 int res = s.onStartCommand(data.args, data.flags, data.startId);
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002155
2156 QueuedWork.waitToFinish();
2157
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002159 ActivityManagerNative.getDefault().serviceDoneExecuting(
2160 data.token, 1, data.startId, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002161 } catch (RemoteException e) {
2162 // nothing to do.
2163 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002164 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165 } catch (Exception e) {
2166 if (!mInstrumentation.onException(s, e)) {
2167 throw new RuntimeException(
2168 "Unable to start service " + s
2169 + " with " + data.args + ": " + e.toString(), e);
2170 }
2171 }
2172 }
2173 }
2174
2175 private final void handleStopService(IBinder token) {
2176 Service s = mServices.remove(token);
2177 if (s != null) {
2178 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002179 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002180 s.onDestroy();
2181 Context context = s.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002182 if (context instanceof ContextImpl) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 final String who = s.getClassName();
Dianne Hackborn21556372010-02-04 16:34:40 -08002184 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002185 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002186
2187 QueuedWork.waitToFinish();
2188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002190 ActivityManagerNative.getDefault().serviceDoneExecuting(
2191 token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002192 } catch (RemoteException e) {
2193 // nothing to do.
2194 }
2195 } catch (Exception e) {
2196 if (!mInstrumentation.onException(s, e)) {
2197 throw new RuntimeException(
2198 "Unable to stop service " + s
2199 + ": " + e.toString(), e);
2200 }
2201 }
2202 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002203 //Slog.i(TAG, "Running services: " + mServices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002204 }
2205
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002206 public final ActivityClientRecord performResumeActivity(IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002207 boolean clearHide) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002208 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002209 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210 + " finished=" + r.activity.mFinished);
2211 if (r != null && !r.activity.mFinished) {
2212 if (clearHide) {
2213 r.hideForNow = false;
2214 r.activity.mStartedActivity = false;
2215 }
2216 try {
2217 if (r.pendingIntents != null) {
2218 deliverNewIntents(r, r.pendingIntents);
2219 r.pendingIntents = null;
2220 }
2221 if (r.pendingResults != null) {
2222 deliverResults(r, r.pendingResults);
2223 r.pendingResults = null;
2224 }
2225 r.activity.performResume();
2226
Bob Leee5408332009-09-04 18:31:17 -07002227 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002228 r.activity.getComponentName().getClassName());
Bob Leee5408332009-09-04 18:31:17 -07002229
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002230 r.paused = false;
2231 r.stopped = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002232 r.state = null;
2233 } catch (Exception e) {
2234 if (!mInstrumentation.onException(r.activity, e)) {
2235 throw new RuntimeException(
2236 "Unable to resume activity "
2237 + r.intent.getComponent().toShortString()
2238 + ": " + e.toString(), e);
2239 }
2240 }
2241 }
2242 return r;
2243 }
2244
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002245 final void cleanUpPendingRemoveWindows(ActivityClientRecord r) {
2246 if (r.mPendingRemoveWindow != null) {
2247 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow);
2248 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken();
2249 if (wtoken != null) {
2250 WindowManagerImpl.getDefault().closeAll(wtoken,
2251 r.activity.getClass().getName(), "Activity");
2252 }
2253 }
2254 r.mPendingRemoveWindow = null;
2255 r.mPendingRemoveWindowManager = null;
2256 }
2257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002258 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
2259 // If we are getting ready to gc after going to the background, well
2260 // we are back active so skip it.
2261 unscheduleGcIdler();
2262
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002263 ActivityClientRecord r = performResumeActivity(token, clearHide);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264
2265 if (r != null) {
2266 final Activity a = r.activity;
2267
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002268 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 TAG, "Resume " + r + " started activity: " +
2270 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2271 + ", finished: " + a.mFinished);
2272
2273 final int forwardBit = isForward ?
2274 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
Bob Leee5408332009-09-04 18:31:17 -07002275
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 // If the window hasn't yet been added to the window manager,
2277 // and this guy didn't finish itself or start another activity,
2278 // then go ahead and add the window.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002279 boolean willBeVisible = !a.mStartedActivity;
2280 if (!willBeVisible) {
2281 try {
2282 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2283 a.getActivityToken());
2284 } catch (RemoteException e) {
2285 }
2286 }
2287 if (r.window == null && !a.mFinished && willBeVisible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 r.window = r.activity.getWindow();
2289 View decor = r.window.getDecorView();
2290 decor.setVisibility(View.INVISIBLE);
2291 ViewManager wm = a.getWindowManager();
2292 WindowManager.LayoutParams l = r.window.getAttributes();
2293 a.mDecor = decor;
2294 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2295 l.softInputMode |= forwardBit;
2296 if (a.mVisibleFromClient) {
2297 a.mWindowAdded = true;
2298 wm.addView(decor, l);
2299 }
2300
2301 // If the window has already been added, but during resume
2302 // we started another activity, then don't yet make the
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002303 // window visible.
2304 } else if (!willBeVisible) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002305 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002306 TAG, "Launch " + r + " mStartedActivity set");
2307 r.hideForNow = true;
2308 }
2309
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002310 // Get rid of anything left hanging around.
2311 cleanUpPendingRemoveWindows(r);
2312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002313 // The window is now visible if it has been added, we are not
2314 // simply finishing, and we are not starting another activity.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002315 if (!r.activity.mFinished && willBeVisible
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002316 && r.activity.mDecor != null && !r.hideForNow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002317 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002318 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002319 + r.activityInfo.name + " with newConfig " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002320 performConfigurationChanged(r.activity, r.newConfig);
2321 r.newConfig = null;
2322 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002323 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002324 + isForward);
2325 WindowManager.LayoutParams l = r.window.getAttributes();
2326 if ((l.softInputMode
2327 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2328 != forwardBit) {
2329 l.softInputMode = (l.softInputMode
2330 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2331 | forwardBit;
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002332 if (r.activity.mVisibleFromClient) {
2333 ViewManager wm = a.getWindowManager();
2334 View decor = r.window.getDecorView();
2335 wm.updateViewLayout(decor, l);
2336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002337 }
2338 r.activity.mVisibleFromServer = true;
2339 mNumVisibleActivities++;
2340 if (r.activity.mVisibleFromClient) {
2341 r.activity.makeVisible();
2342 }
2343 }
2344
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002345 if (!r.onlyLocalRequest) {
2346 r.nextIdle = mNewActivities;
2347 mNewActivities = r;
2348 if (localLOGV) Slog.v(
2349 TAG, "Scheduling idle handler for " + r);
2350 Looper.myQueue().addIdleHandler(new Idler());
2351 }
2352 r.onlyLocalRequest = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002353
2354 } else {
2355 // If an exception was thrown when trying to resume, then
2356 // just end this activity.
2357 try {
2358 ActivityManagerNative.getDefault()
2359 .finishActivity(token, Activity.RESULT_CANCELED, null);
2360 } catch (RemoteException ex) {
2361 }
2362 }
2363 }
2364
2365 private int mThumbnailWidth = -1;
2366 private int mThumbnailHeight = -1;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002367 private Bitmap mAvailThumbnailBitmap = null;
2368 private Canvas mThumbnailCanvas = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002369
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002370 private final Bitmap createThumbnailBitmap(ActivityClientRecord r) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002371 Bitmap thumbnail = mAvailThumbnailBitmap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002372 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002373 if (thumbnail == null) {
2374 int w = mThumbnailWidth;
2375 int h;
2376 if (w < 0) {
2377 Resources res = r.activity.getResources();
2378 mThumbnailHeight = h =
2379 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002380
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002381 mThumbnailWidth = w =
2382 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2383 } else {
2384 h = mThumbnailHeight;
2385 }
2386
2387 // On platforms where we don't want thumbnails, set dims to (0,0)
2388 if ((w > 0) && (h > 0)) {
2389 thumbnail = Bitmap.createBitmap(w, h, THUMBNAIL_FORMAT);
2390 thumbnail.eraseColor(0);
2391 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002392 }
2393
Dianne Hackbornfb3806d2010-12-09 13:14:12 -08002394 if (thumbnail != null) {
2395 Canvas cv = mThumbnailCanvas;
2396 if (cv == null) {
2397 mThumbnailCanvas = cv = new Canvas();
2398 }
2399
2400 cv.setBitmap(thumbnail);
2401 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2402 mAvailThumbnailBitmap = thumbnail;
2403 thumbnail = null;
2404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002405 }
Jim Miller0b2a6d02010-07-13 18:01:29 -07002406
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002407 } catch (Exception e) {
2408 if (!mInstrumentation.onException(r.activity, e)) {
2409 throw new RuntimeException(
2410 "Unable to create thumbnail of "
2411 + r.intent.getComponent().toShortString()
2412 + ": " + e.toString(), e);
2413 }
2414 thumbnail = null;
2415 }
2416
2417 return thumbnail;
2418 }
2419
2420 private final void handlePauseActivity(IBinder token, boolean finished,
2421 boolean userLeaving, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002422 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002424 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002425 if (userLeaving) {
2426 performUserLeavingActivity(r);
2427 }
Bob Leee5408332009-09-04 18:31:17 -07002428
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002429 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002430 performPauseActivity(token, finished, r.isPreHoneycomb());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002431
Dianne Hackbornaa93bcd2010-10-27 13:57:00 -07002432 // Make sure any pending writes are now committed.
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002433 if (r.isPreHoneycomb()) {
2434 QueuedWork.waitToFinish();
2435 }
Dianne Hackbornaa93bcd2010-10-27 13:57:00 -07002436
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002437 // Tell the activity manager we have paused.
2438 try {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002439 ActivityManagerNative.getDefault().activityPaused(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002440 } catch (RemoteException ex) {
2441 }
2442 }
2443 }
2444
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002445 final void performUserLeavingActivity(ActivityClientRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446 mInstrumentation.callActivityOnUserLeaving(r.activity);
2447 }
2448
2449 final Bundle performPauseActivity(IBinder token, boolean finished,
2450 boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002451 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002452 return r != null ? performPauseActivity(r, finished, saveState) : null;
2453 }
2454
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002455 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002456 boolean saveState) {
2457 if (r.paused) {
2458 if (r.activity.mFinished) {
2459 // If we are finishing, we won't call onResume() in certain cases.
2460 // So here we likewise don't want to call onPause() if the activity
2461 // isn't resumed.
2462 return null;
2463 }
2464 RuntimeException e = new RuntimeException(
2465 "Performing pause of activity that is not resumed: "
2466 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002467 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002468 }
2469 Bundle state = null;
2470 if (finished) {
2471 r.activity.mFinished = true;
2472 }
2473 try {
2474 // Next have the activity save its current state and managed dialogs...
2475 if (!r.activity.mFinished && saveState) {
2476 state = new Bundle();
2477 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2478 r.state = state;
2479 }
2480 // Now we are idle.
2481 r.activity.mCalled = false;
2482 mInstrumentation.callActivityOnPause(r.activity);
2483 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
2484 if (!r.activity.mCalled) {
2485 throw new SuperNotCalledException(
2486 "Activity " + r.intent.getComponent().toShortString() +
2487 " did not call through to super.onPause()");
2488 }
2489
2490 } catch (SuperNotCalledException e) {
2491 throw e;
2492
2493 } catch (Exception e) {
2494 if (!mInstrumentation.onException(r.activity, e)) {
2495 throw new RuntimeException(
2496 "Unable to pause activity "
2497 + r.intent.getComponent().toShortString()
2498 + ": " + e.toString(), e);
2499 }
2500 }
2501 r.paused = true;
Jeff Hamilton52d32032011-01-08 15:31:26 -06002502
2503 // Notify any outstanding on paused listeners
2504 ArrayList<OnActivityPausedListener> listeners;
2505 synchronized (mOnPauseListeners) {
2506 listeners = mOnPauseListeners.remove(r.activity);
2507 }
2508 int size = (listeners != null ? listeners.size() : 0);
2509 for (int i = 0; i < size; i++) {
2510 listeners.get(i).onPaused(r.activity);
2511 }
2512
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 return state;
2514 }
2515
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002516 final void performStopActivity(IBinder token, boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002517 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002518 performStopActivityInner(r, null, false, saveState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 }
2520
2521 private static class StopInfo {
2522 Bitmap thumbnail;
2523 CharSequence description;
2524 }
2525
2526 private final class ProviderRefCount {
2527 public int count;
2528 ProviderRefCount(int pCount) {
2529 count = pCount;
2530 }
2531 }
2532
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002533 /**
2534 * Core implementation of stopping an activity. Note this is a little
2535 * tricky because the server's meaning of stop is slightly different
2536 * than our client -- for the server, stop means to save state and give
2537 * it the result when it is done, but the window may still be visible.
2538 * For the client, we want to call onStop()/onStart() to indicate when
2539 * the activity's UI visibillity changes.
2540 */
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002541 private final void performStopActivityInner(ActivityClientRecord r,
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002542 StopInfo info, boolean keepShown, boolean saveState) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002543 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002544 Bundle state = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002545 if (r != null) {
2546 if (!keepShown && r.stopped) {
2547 if (r.activity.mFinished) {
2548 // If we are finishing, we won't call onResume() in certain
2549 // cases. So here we likewise don't want to call onStop()
2550 // if the activity isn't resumed.
2551 return;
2552 }
2553 RuntimeException e = new RuntimeException(
2554 "Performing stop of activity that is not resumed: "
2555 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002556 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002557 }
2558
2559 if (info != null) {
2560 try {
2561 // First create a thumbnail for the activity...
Jim Miller0b2a6d02010-07-13 18:01:29 -07002562 info.thumbnail = createThumbnailBitmap(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002563 info.description = r.activity.onCreateDescription();
2564 } catch (Exception e) {
2565 if (!mInstrumentation.onException(r.activity, e)) {
2566 throw new RuntimeException(
2567 "Unable to save state of activity "
2568 + r.intent.getComponent().toShortString()
2569 + ": " + e.toString(), e);
2570 }
2571 }
2572 }
2573
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002574 // Next have the activity save its current state and managed dialogs...
2575 if (!r.activity.mFinished && saveState) {
2576 if (r.state == null) {
2577 state = new Bundle();
2578 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2579 r.state = state;
2580 } else {
2581 state = r.state;
2582 }
2583 }
2584
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 if (!keepShown) {
2586 try {
2587 // Now we are idle.
2588 r.activity.performStop();
2589 } catch (Exception e) {
2590 if (!mInstrumentation.onException(r.activity, e)) {
2591 throw new RuntimeException(
2592 "Unable to stop activity "
2593 + r.intent.getComponent().toShortString()
2594 + ": " + e.toString(), e);
2595 }
2596 }
2597 r.stopped = true;
2598 }
2599
2600 r.paused = true;
2601 }
2602 }
2603
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002604 private final void updateVisibility(ActivityClientRecord r, boolean show) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002605 View v = r.activity.mDecor;
2606 if (v != null) {
2607 if (show) {
2608 if (!r.activity.mVisibleFromServer) {
2609 r.activity.mVisibleFromServer = true;
2610 mNumVisibleActivities++;
2611 if (r.activity.mVisibleFromClient) {
2612 r.activity.makeVisible();
2613 }
2614 }
2615 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002616 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002617 + r.activityInfo.name + " with new config " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002618 performConfigurationChanged(r.activity, r.newConfig);
2619 r.newConfig = null;
2620 }
2621 } else {
2622 if (r.activity.mVisibleFromServer) {
2623 r.activity.mVisibleFromServer = false;
2624 mNumVisibleActivities--;
2625 v.setVisibility(View.INVISIBLE);
2626 }
2627 }
2628 }
2629 }
2630
2631 private final void handleStopActivity(IBinder token, boolean show, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002632 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002633 r.activity.mConfigChangeFlags |= configChanges;
2634
2635 StopInfo info = new StopInfo();
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002636 performStopActivityInner(r, info, show, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002637
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002638 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002639 TAG, "Finishing stop of " + r + ": show=" + show
2640 + " win=" + r.window);
2641
2642 updateVisibility(r, show);
Bob Leee5408332009-09-04 18:31:17 -07002643
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002644 // Make sure any pending writes are now committed.
2645 if (!r.isPreHoneycomb()) {
2646 QueuedWork.waitToFinish();
2647 }
2648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002649 // Tell activity manager we have been stopped.
2650 try {
2651 ActivityManagerNative.getDefault().activityStopped(
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002652 r.token, r.state, info.thumbnail, info.description);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002653 } catch (RemoteException ex) {
2654 }
2655 }
2656
2657 final void performRestartActivity(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002658 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002659 if (r.stopped) {
2660 r.activity.performRestart();
2661 r.stopped = false;
2662 }
2663 }
2664
2665 private final void handleWindowVisibility(IBinder token, boolean show) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002666 ActivityClientRecord r = mActivities.get(token);
Dianne Hackbornbfddc0f2010-12-14 11:28:01 -08002667
2668 if (r == null) {
2669 Log.w(TAG, "handleWindowVisibility: no activity for token " + token);
2670 return;
2671 }
2672
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002673 if (!show && !r.stopped) {
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08002674 performStopActivityInner(r, null, show, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002675 } else if (show && r.stopped) {
2676 // If we are getting ready to gc after going to the background, well
2677 // we are back active so skip it.
2678 unscheduleGcIdler();
2679
2680 r.activity.performRestart();
2681 r.stopped = false;
2682 }
2683 if (r.activity.mDecor != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002684 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685 TAG, "Handle window " + r + " visibility: " + show);
2686 updateVisibility(r, show);
2687 }
2688 }
2689
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002690 private final void handleSleeping(IBinder token, boolean sleeping) {
2691 ActivityClientRecord r = mActivities.get(token);
2692
2693 if (r == null) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08002694 Log.w(TAG, "handleSleeping: no activity for token " + token);
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002695 return;
2696 }
2697
2698 if (sleeping) {
Dianne Hackborn842e04b2011-01-22 13:00:12 -08002699 if (!r.stopped && !r.isPreHoneycomb()) {
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002700 try {
2701 // Now we are idle.
2702 r.activity.performStop();
2703 } catch (Exception e) {
2704 if (!mInstrumentation.onException(r.activity, e)) {
2705 throw new RuntimeException(
2706 "Unable to stop activity "
2707 + r.intent.getComponent().toShortString()
2708 + ": " + e.toString(), e);
2709 }
2710 }
2711 r.stopped = true;
2712 }
Dianne Hackborn5d9d03a2011-01-24 13:15:09 -08002713
2714 // Make sure any pending writes are now committed.
2715 if (!r.isPreHoneycomb()) {
2716 QueuedWork.waitToFinish();
2717 }
2718
Dianne Hackborn4eba96b2011-01-21 13:34:36 -08002719 // Tell activity manager we slept.
2720 try {
2721 ActivityManagerNative.getDefault().activitySlept(r.token);
2722 } catch (RemoteException ex) {
2723 }
2724 } else {
2725 if (r.stopped && r.activity.mVisibleFromServer) {
2726 r.activity.performRestart();
2727 r.stopped = false;
2728 }
2729 }
2730 }
2731
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08002732 private void handleSetCoreSettings(Bundle coreSettings) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08002733 synchronized (mPackages) {
2734 mCoreSettings = coreSettings;
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08002735 }
2736 }
2737
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002738 private final void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002739 final int N = results.size();
2740 for (int i=0; i<N; i++) {
2741 ResultInfo ri = results.get(i);
2742 try {
2743 if (ri.mData != null) {
2744 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
2745 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002746 if (DEBUG_RESULTS) Slog.v(TAG,
Chris Tate8a7dc172009-03-24 20:11:42 -07002747 "Delivering result to activity " + r + " : " + ri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 r.activity.dispatchActivityResult(ri.mResultWho,
2749 ri.mRequestCode, ri.mResultCode, ri.mData);
2750 } catch (Exception e) {
2751 if (!mInstrumentation.onException(r.activity, e)) {
2752 throw new RuntimeException(
2753 "Failure delivering result " + ri + " to activity "
2754 + r.intent.getComponent().toShortString()
2755 + ": " + e.toString(), e);
2756 }
2757 }
2758 }
2759 }
2760
2761 private final void handleSendResult(ResultData res) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002762 ActivityClientRecord r = mActivities.get(res.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002763 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 if (r != null) {
2765 final boolean resumed = !r.paused;
2766 if (!r.activity.mFinished && r.activity.mDecor != null
2767 && r.hideForNow && resumed) {
2768 // We had hidden the activity because it started another
2769 // one... we have gotten a result back and we are not
2770 // paused, so make sure our window is visible.
2771 updateVisibility(r, true);
2772 }
2773 if (resumed) {
2774 try {
2775 // Now we are idle.
2776 r.activity.mCalled = false;
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002777 r.activity.mTemporaryPause = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 mInstrumentation.callActivityOnPause(r.activity);
2779 if (!r.activity.mCalled) {
2780 throw new SuperNotCalledException(
2781 "Activity " + r.intent.getComponent().toShortString()
2782 + " did not call through to super.onPause()");
2783 }
2784 } catch (SuperNotCalledException e) {
2785 throw e;
2786 } catch (Exception e) {
2787 if (!mInstrumentation.onException(r.activity, e)) {
2788 throw new RuntimeException(
2789 "Unable to pause activity "
2790 + r.intent.getComponent().toShortString()
2791 + ": " + e.toString(), e);
2792 }
2793 }
2794 }
2795 deliverResults(r, res.results);
2796 if (resumed) {
2797 mInstrumentation.callActivityOnResume(r.activity);
Dianne Hackbornfb3cffe2010-10-25 17:08:56 -07002798 r.activity.mTemporaryPause = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002799 }
2800 }
2801 }
2802
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002803 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002804 return performDestroyActivity(token, finishing, 0, false);
2805 }
2806
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002807 private final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002808 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002809 ActivityClientRecord r = mActivities.get(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002810 Class activityClass = null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002811 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002812 if (r != null) {
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002813 activityClass = r.activity.getClass();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002814 r.activity.mConfigChangeFlags |= configChanges;
2815 if (finishing) {
2816 r.activity.mFinished = true;
2817 }
2818 if (!r.paused) {
2819 try {
2820 r.activity.mCalled = false;
2821 mInstrumentation.callActivityOnPause(r.activity);
Bob Leee5408332009-09-04 18:31:17 -07002822 EventLog.writeEvent(LOG_ON_PAUSE_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002823 r.activity.getComponentName().getClassName());
2824 if (!r.activity.mCalled) {
2825 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002826 "Activity " + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002827 + " did not call through to super.onPause()");
2828 }
2829 } catch (SuperNotCalledException e) {
2830 throw e;
2831 } catch (Exception e) {
2832 if (!mInstrumentation.onException(r.activity, e)) {
2833 throw new RuntimeException(
2834 "Unable to pause activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002835 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002836 + ": " + e.toString(), e);
2837 }
2838 }
2839 r.paused = true;
2840 }
2841 if (!r.stopped) {
2842 try {
2843 r.activity.performStop();
2844 } catch (SuperNotCalledException e) {
2845 throw e;
2846 } catch (Exception e) {
2847 if (!mInstrumentation.onException(r.activity, e)) {
2848 throw new RuntimeException(
2849 "Unable to stop activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002850 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002851 + ": " + e.toString(), e);
2852 }
2853 }
2854 r.stopped = true;
2855 }
2856 if (getNonConfigInstance) {
2857 try {
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002858 r.lastNonConfigurationInstances
2859 = r.activity.retainNonConfigurationInstances();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002860 } catch (Exception e) {
2861 if (!mInstrumentation.onException(r.activity, e)) {
2862 throw new RuntimeException(
2863 "Unable to retain activity "
2864 + r.intent.getComponent().toShortString()
2865 + ": " + e.toString(), e);
2866 }
2867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002868 }
2869 try {
2870 r.activity.mCalled = false;
Dianne Hackborn2dedce62010-04-15 14:45:25 -07002871 mInstrumentation.callActivityOnDestroy(r.activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002872 if (!r.activity.mCalled) {
2873 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002874 "Activity " + safeToComponentShortString(r.intent) +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002875 " did not call through to super.onDestroy()");
2876 }
2877 if (r.window != null) {
2878 r.window.closeAllPanels();
2879 }
2880 } catch (SuperNotCalledException e) {
2881 throw e;
2882 } catch (Exception e) {
2883 if (!mInstrumentation.onException(r.activity, e)) {
2884 throw new RuntimeException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002885 "Unable to destroy activity " + safeToComponentShortString(r.intent)
2886 + ": " + e.toString(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002887 }
2888 }
2889 }
2890 mActivities.remove(token);
Brad Fitzpatrick5f8b5c12011-01-20 15:12:08 -08002891 StrictMode.decrementExpectedActivityCount(activityClass);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002892 return r;
2893 }
2894
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002895 private static String safeToComponentShortString(Intent intent) {
2896 ComponentName component = intent.getComponent();
2897 return component == null ? "[Unknown]" : component.toShortString();
2898 }
2899
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002900 private final void handleDestroyActivity(IBinder token, boolean finishing,
2901 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002902 ActivityClientRecord r = performDestroyActivity(token, finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002903 configChanges, getNonConfigInstance);
2904 if (r != null) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002905 cleanUpPendingRemoveWindows(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002906 WindowManager wm = r.activity.getWindowManager();
2907 View v = r.activity.mDecor;
2908 if (v != null) {
2909 if (r.activity.mVisibleFromServer) {
2910 mNumVisibleActivities--;
2911 }
2912 IBinder wtoken = v.getWindowToken();
2913 if (r.activity.mWindowAdded) {
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002914 if (r.onlyLocalRequest) {
2915 // Hold off on removing this until the new activity's
2916 // window is being added.
2917 r.mPendingRemoveWindow = v;
2918 r.mPendingRemoveWindowManager = wm;
2919 } else {
2920 wm.removeViewImmediate(v);
2921 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002922 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002923 if (wtoken != null && r.mPendingRemoveWindow == null) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002924 WindowManagerImpl.getDefault().closeAll(wtoken,
2925 r.activity.getClass().getName(), "Activity");
2926 }
2927 r.activity.mDecor = null;
2928 }
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002929 if (r.mPendingRemoveWindow == null) {
2930 // If we are delaying the removal of the activity window, then
2931 // we can't clean up all windows here. Note that we can't do
2932 // so later either, which means any windows that aren't closed
2933 // by the app will leak. Well we try to warning them a lot
2934 // about leaking windows, because that is a bug, so if they are
2935 // using this recreate facility then they get to live with leaks.
2936 WindowManagerImpl.getDefault().closeAll(token,
2937 r.activity.getClass().getName(), "Activity");
2938 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002939
2940 // Mocked out contexts won't be participating in the normal
2941 // process lifecycle, but if we're running with a proper
2942 // ApplicationContext we need to have it tear down things
2943 // cleanly.
2944 Context c = r.activity.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002945 if (c instanceof ContextImpl) {
2946 ((ContextImpl) c).scheduleFinalCleanup(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002947 r.activity.getClass().getName(), "Activity");
2948 }
2949 }
2950 if (finishing) {
2951 try {
2952 ActivityManagerNative.getDefault().activityDestroyed(token);
2953 } catch (RemoteException ex) {
2954 // If the system process has died, it's game over for everyone.
2955 }
2956 }
2957 }
2958
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08002959 public final void requestRelaunchActivity(IBinder token,
2960 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
2961 int configChanges, boolean notResumed, Configuration config,
2962 boolean fromServer) {
2963 ActivityClientRecord target = null;
2964
2965 synchronized (mPackages) {
2966 for (int i=0; i<mRelaunchingActivities.size(); i++) {
2967 ActivityClientRecord r = mRelaunchingActivities.get(i);
2968 if (r.token == token) {
2969 target = r;
2970 if (pendingResults != null) {
2971 if (r.pendingResults != null) {
2972 r.pendingResults.addAll(pendingResults);
2973 } else {
2974 r.pendingResults = pendingResults;
2975 }
2976 }
2977 if (pendingNewIntents != null) {
2978 if (r.pendingIntents != null) {
2979 r.pendingIntents.addAll(pendingNewIntents);
2980 } else {
2981 r.pendingIntents = pendingNewIntents;
2982 }
2983 }
2984 break;
2985 }
2986 }
2987
2988 if (target == null) {
2989 target = new ActivityClientRecord();
2990 target.token = token;
2991 target.pendingResults = pendingResults;
2992 target.pendingIntents = pendingNewIntents;
2993 if (!fromServer) {
2994 ActivityClientRecord existing = mActivities.get(token);
2995 if (existing != null) {
2996 target.startsNotResumed = existing.paused;
2997 }
2998 target.onlyLocalRequest = true;
2999 }
3000 mRelaunchingActivities.add(target);
3001 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target);
3002 }
3003
3004 if (fromServer) {
3005 target.startsNotResumed = notResumed;
3006 target.onlyLocalRequest = false;
3007 }
3008 if (config != null) {
3009 target.createdConfig = config;
3010 }
3011 target.pendingConfigChanges |= configChanges;
3012 }
3013 }
3014
3015 private final void handleRelaunchActivity(ActivityClientRecord tmp) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003016 // If we are getting ready to gc after going to the background, well
3017 // we are back active so skip it.
3018 unscheduleGcIdler();
3019
3020 Configuration changedConfig = null;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003021 int configChanges = 0;
Bob Leee5408332009-09-04 18:31:17 -07003022
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003023 // First: make sure we have the most recent configuration and most
3024 // recent version of the activity, or skip it if some previous call
3025 // had taken a more recent version.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003026 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003027 int N = mRelaunchingActivities.size();
3028 IBinder token = tmp.token;
3029 tmp = null;
3030 for (int i=0; i<N; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003031 ActivityClientRecord r = mRelaunchingActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003032 if (r.token == token) {
3033 tmp = r;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003034 configChanges |= tmp.pendingConfigChanges;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003035 mRelaunchingActivities.remove(i);
3036 i--;
3037 N--;
3038 }
3039 }
Bob Leee5408332009-09-04 18:31:17 -07003040
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003041 if (tmp == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003042 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003043 return;
3044 }
Bob Leee5408332009-09-04 18:31:17 -07003045
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003046 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
3047 + tmp.token + " with configChanges=0x"
3048 + Integer.toHexString(configChanges));
3049
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003050 if (mPendingConfiguration != null) {
3051 changedConfig = mPendingConfiguration;
3052 mPendingConfiguration = null;
3053 }
3054 }
Bob Leee5408332009-09-04 18:31:17 -07003055
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003056 if (tmp.createdConfig != null) {
3057 // If the activity manager is passing us its current config,
3058 // assume that is really what we want regardless of what we
3059 // may have pending.
3060 if (mConfiguration == null
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003061 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
3062 && mConfiguration.diff(tmp.createdConfig) != 0)) {
3063 if (changedConfig == null
3064 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
3065 changedConfig = tmp.createdConfig;
3066 }
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08003067 }
3068 }
3069
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003070 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003071 + tmp.token + ": changedConfig=" + changedConfig);
3072
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 // If there was a pending configuration change, execute it first.
3074 if (changedConfig != null) {
3075 handleConfigurationChanged(changedConfig);
3076 }
Bob Leee5408332009-09-04 18:31:17 -07003077
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003078 ActivityClientRecord r = mActivities.get(tmp.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003079 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003080 if (r == null) {
3081 return;
3082 }
Bob Leee5408332009-09-04 18:31:17 -07003083
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003084 r.activity.mConfigChangeFlags |= configChanges;
Dianne Hackborn30c9bd82010-12-01 16:07:40 -08003085 r.onlyLocalRequest = tmp.onlyLocalRequest;
Christopher Tateb70f3df2009-04-07 16:07:59 -07003086 Intent currentIntent = r.activity.mIntent;
Bob Leee5408332009-09-04 18:31:17 -07003087
Dianne Hackborn0aae2d42010-12-07 23:51:29 -08003088 r.activity.mChangingConfigurations = true;
3089
Dianne Hackborne2b04802010-12-09 09:24:55 -08003090 // Need to ensure state is saved.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003091 if (!r.paused) {
Dianne Hackborne2b04802010-12-09 09:24:55 -08003092 performPauseActivity(r.token, false, r.isPreHoneycomb());
3093 }
3094 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
3095 r.state = new Bundle();
3096 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003097 }
Bob Leee5408332009-09-04 18:31:17 -07003098
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003099 handleDestroyActivity(r.token, false, configChanges, true);
Bob Leee5408332009-09-04 18:31:17 -07003100
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003101 r.activity = null;
3102 r.window = null;
3103 r.hideForNow = false;
3104 r.nextIdle = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07003105 // Merge any pending results and pending intents; don't just replace them
3106 if (tmp.pendingResults != null) {
3107 if (r.pendingResults == null) {
3108 r.pendingResults = tmp.pendingResults;
3109 } else {
3110 r.pendingResults.addAll(tmp.pendingResults);
3111 }
3112 }
3113 if (tmp.pendingIntents != null) {
3114 if (r.pendingIntents == null) {
3115 r.pendingIntents = tmp.pendingIntents;
3116 } else {
3117 r.pendingIntents.addAll(tmp.pendingIntents);
3118 }
3119 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003120 r.startsNotResumed = tmp.startsNotResumed;
Bob Leee5408332009-09-04 18:31:17 -07003121
Christopher Tateb70f3df2009-04-07 16:07:59 -07003122 handleLaunchActivity(r, currentIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003123 }
3124
3125 private final void handleRequestThumbnail(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003126 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003127 Bitmap thumbnail = createThumbnailBitmap(r);
3128 CharSequence description = null;
3129 try {
3130 description = r.activity.onCreateDescription();
3131 } catch (Exception e) {
3132 if (!mInstrumentation.onException(r.activity, e)) {
3133 throw new RuntimeException(
3134 "Unable to create description of activity "
3135 + r.intent.getComponent().toShortString()
3136 + ": " + e.toString(), e);
3137 }
3138 }
3139 //System.out.println("Reporting top thumbnail " + thumbnail);
3140 try {
3141 ActivityManagerNative.getDefault().reportThumbnail(
3142 token, thumbnail, description);
3143 } catch (RemoteException ex) {
3144 }
3145 }
3146
3147 ArrayList<ComponentCallbacks> collectComponentCallbacksLocked(
3148 boolean allActivities, Configuration newConfig) {
3149 ArrayList<ComponentCallbacks> callbacks
3150 = new ArrayList<ComponentCallbacks>();
Bob Leee5408332009-09-04 18:31:17 -07003151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003152 if (mActivities.size() > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003153 Iterator<ActivityClientRecord> it = mActivities.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003154 while (it.hasNext()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003155 ActivityClientRecord ar = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003156 Activity a = ar.activity;
3157 if (a != null) {
3158 if (!ar.activity.mFinished && (allActivities ||
3159 (a != null && !ar.paused))) {
3160 // If the activity is currently resumed, its configuration
3161 // needs to change right now.
3162 callbacks.add(a);
3163 } else if (newConfig != null) {
3164 // Otherwise, we will tell it about the change
3165 // the next time it is resumed or shown. Note that
3166 // the activity manager may, before then, decide the
3167 // activity needs to be destroyed to handle its new
3168 // configuration.
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003169 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Setting activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003170 + ar.activityInfo.name + " newConfig=" + newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003171 ar.newConfig = newConfig;
3172 }
3173 }
3174 }
3175 }
3176 if (mServices.size() > 0) {
3177 Iterator<Service> it = mServices.values().iterator();
3178 while (it.hasNext()) {
3179 callbacks.add(it.next());
3180 }
3181 }
3182 synchronized (mProviderMap) {
3183 if (mLocalProviders.size() > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003184 Iterator<ProviderClientRecord> it = mLocalProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003185 while (it.hasNext()) {
3186 callbacks.add(it.next().mLocalProvider);
3187 }
3188 }
3189 }
3190 final int N = mAllApplications.size();
3191 for (int i=0; i<N; i++) {
3192 callbacks.add(mAllApplications.get(i));
3193 }
Bob Leee5408332009-09-04 18:31:17 -07003194
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003195 return callbacks;
3196 }
Bob Leee5408332009-09-04 18:31:17 -07003197
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003198 private final void performConfigurationChanged(
3199 ComponentCallbacks cb, Configuration config) {
3200 // Only for Activity objects, check that they actually call up to their
3201 // superclass implementation. ComponentCallbacks is an interface, so
3202 // we check the runtime type and act accordingly.
3203 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
3204 if (activity != null) {
3205 activity.mCalled = false;
3206 }
Bob Leee5408332009-09-04 18:31:17 -07003207
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003208 boolean shouldChangeConfig = false;
3209 if ((activity == null) || (activity.mCurrentConfig == null)) {
3210 shouldChangeConfig = true;
3211 } else {
Bob Leee5408332009-09-04 18:31:17 -07003212
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003213 // If the new config is the same as the config this Activity
3214 // is already running with then don't bother calling
3215 // onConfigurationChanged
3216 int diff = activity.mCurrentConfig.diff(config);
3217 if (diff != 0) {
Bob Leee5408332009-09-04 18:31:17 -07003218
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003219 // If this activity doesn't handle any of the config changes
3220 // then don't bother calling onConfigurationChanged as we're
3221 // going to destroy it.
3222 if ((~activity.mActivityInfo.configChanges & diff) == 0) {
3223 shouldChangeConfig = true;
3224 }
3225 }
3226 }
Bob Leee5408332009-09-04 18:31:17 -07003227
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003228 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003229 + ": shouldChangeConfig=" + shouldChangeConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003230 if (shouldChangeConfig) {
3231 cb.onConfigurationChanged(config);
Bob Leee5408332009-09-04 18:31:17 -07003232
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003233 if (activity != null) {
3234 if (!activity.mCalled) {
3235 throw new SuperNotCalledException(
3236 "Activity " + activity.getLocalClassName() +
3237 " did not call through to super.onConfigurationChanged()");
3238 }
3239 activity.mConfigChangeFlags = 0;
3240 activity.mCurrentConfig = new Configuration(config);
3241 }
3242 }
3243 }
3244
Dianne Hackbornae078162010-03-18 11:29:37 -07003245 final boolean applyConfigurationToResourcesLocked(Configuration config) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003246 if (mResConfiguration == null) {
3247 mResConfiguration = new Configuration();
3248 }
3249 if (!mResConfiguration.isOtherSeqNewer(config)) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003250 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003251 + mResConfiguration.seq + ", newSeq=" + config.seq);
Dianne Hackbornae078162010-03-18 11:29:37 -07003252 return false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003253 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003254 int changes = mResConfiguration.updateFrom(config);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003255 DisplayMetrics dm = getDisplayMetricsLocked(true);
Bob Leee5408332009-09-04 18:31:17 -07003256
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003257 // set it for java, this also affects newly created Resources
3258 if (config.locale != null) {
3259 Locale.setDefault(config.locale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003260 }
Bob Leee5408332009-09-04 18:31:17 -07003261
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003262 Resources.updateSystemConfiguration(config, dm);
Bob Leee5408332009-09-04 18:31:17 -07003263
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08003264 ApplicationPackageManager.configurationChanged();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003265 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003266
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003267 Iterator<WeakReference<Resources>> it =
3268 mActiveResources.values().iterator();
3269 //Iterator<Map.Entry<String, WeakReference<Resources>>> it =
3270 // mActiveResources.entrySet().iterator();
3271 while (it.hasNext()) {
3272 WeakReference<Resources> v = it.next();
3273 Resources r = v.get();
3274 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003275 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003276 + r + " config to: " + config);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003277 r.updateConfiguration(config, dm);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003278 //Slog.i(TAG, "Updated app resources " + v.getKey()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003279 // + " " + r + ": " + r.getConfiguration());
3280 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003281 //Slog.i(TAG, "Removing old resources " + v.getKey());
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003282 it.remove();
3283 }
3284 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003285
3286 return changes != 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003287 }
3288
3289 final void handleConfigurationChanged(Configuration config) {
3290
3291 ArrayList<ComponentCallbacks> callbacks = null;
3292
3293 synchronized (mPackages) {
3294 if (mPendingConfiguration != null) {
3295 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3296 config = mPendingConfiguration;
3297 }
3298 mPendingConfiguration = null;
3299 }
3300
3301 if (config == null) {
3302 return;
3303 }
3304
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003305 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003306 + config);
3307
3308 applyConfigurationToResourcesLocked(config);
3309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003310 if (mConfiguration == null) {
3311 mConfiguration = new Configuration();
3312 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003313 if (!mConfiguration.isOtherSeqNewer(config)) {
3314 return;
3315 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003316 mConfiguration.updateFrom(config);
Bob Leee5408332009-09-04 18:31:17 -07003317
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003318 callbacks = collectComponentCallbacksLocked(false, config);
3319 }
Bob Leee5408332009-09-04 18:31:17 -07003320
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003321 if (callbacks != null) {
3322 final int N = callbacks.size();
3323 for (int i=0; i<N; i++) {
3324 performConfigurationChanged(callbacks.get(i), config);
3325 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003326 }
3327 }
3328
3329 final void handleActivityConfigurationChanged(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003330 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003331 if (r == null || r.activity == null) {
3332 return;
3333 }
Bob Leee5408332009-09-04 18:31:17 -07003334
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003335 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003336 + r.activityInfo.name);
3337
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003338 performConfigurationChanged(r.activity, mConfiguration);
3339 }
3340
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003341 final void handleProfilerControl(boolean start, ProfilerControlData pcd) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003342 if (start) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003343 try {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003344 Debug.startMethodTracing(pcd.path, pcd.fd.getFileDescriptor(),
3345 8 * 1024 * 1024, 0);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003346 } catch (RuntimeException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003347 Slog.w(TAG, "Profiling failed on path " + pcd.path
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003348 + " -- can the process access this path?");
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003349 } finally {
3350 try {
3351 pcd.fd.close();
3352 } catch (IOException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003353 Slog.w(TAG, "Failure closing profile fd", e);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003354 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003355 }
3356 } else {
3357 Debug.stopMethodTracing();
3358 }
3359 }
Bob Leee5408332009-09-04 18:31:17 -07003360
Andy McFadden824c5102010-07-09 16:26:57 -07003361 final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
3362 if (managed) {
3363 try {
3364 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
3365 } catch (IOException e) {
3366 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
3367 + " -- can the process access this path?");
3368 } finally {
3369 try {
3370 dhd.fd.close();
3371 } catch (IOException e) {
3372 Slog.w(TAG, "Failure closing profile fd", e);
3373 }
3374 }
3375 } else {
Andy McFadden06a6b552010-07-13 16:28:09 -07003376 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
Andy McFadden824c5102010-07-09 16:26:57 -07003377 }
3378 }
3379
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003380 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
3381 boolean hasPkgInfo = false;
3382 if (packages != null) {
3383 for (int i=packages.length-1; i>=0; i--) {
3384 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
3385 if (!hasPkgInfo) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003386 WeakReference<LoadedApk> ref;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003387 ref = mPackages.get(packages[i]);
3388 if (ref != null && ref.get() != null) {
3389 hasPkgInfo = true;
3390 } else {
3391 ref = mResourcePackages.get(packages[i]);
3392 if (ref != null && ref.get() != null) {
3393 hasPkgInfo = true;
3394 }
3395 }
3396 }
3397 mPackages.remove(packages[i]);
3398 mResourcePackages.remove(packages[i]);
3399 }
3400 }
Brad Fitzpatrick390dae12010-11-10 08:27:28 -08003401 ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003402 hasPkgInfo);
3403 }
3404
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003405 final void handleLowMemory() {
Brian Carlstromed7e0072011-03-24 13:27:57 -07003406 ArrayList<ComponentCallbacks> callbacks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003407
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003408 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003409 callbacks = collectComponentCallbacksLocked(true, null);
3410 }
Bob Leee5408332009-09-04 18:31:17 -07003411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003412 final int N = callbacks.size();
3413 for (int i=0; i<N; i++) {
3414 callbacks.get(i).onLowMemory();
3415 }
3416
Chris Tatece229052009-03-25 16:44:52 -07003417 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
3418 if (Process.myUid() != Process.SYSTEM_UID) {
3419 int sqliteReleased = SQLiteDatabase.releaseMemory();
3420 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
3421 }
Bob Leee5408332009-09-04 18:31:17 -07003422
Mike Reedcaf0df12009-04-27 14:32:05 -04003423 // Ask graphics to free up as much as possible (font/image caches)
3424 Canvas.freeCaches();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003425
3426 BinderInternal.forceGc("mem");
3427 }
3428
3429 private final void handleBindApplication(AppBindData data) {
3430 mBoundApplication = data;
3431 mConfiguration = new Configuration(data.config);
3432
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003433 // send up app name; do this *before* waiting for debugger
Christopher Tate8ee038d2009-11-06 11:30:20 -08003434 Process.setArgV0(data.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003435 android.ddm.DdmHandleAppName.setAppName(data.processName);
3436
Joe Onoratod630f102011-03-17 18:42:26 -07003437 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask
3438 // implementation to use the pool executor. Normally, we use the
3439 // serialized executor as the default. This has to happen in the
3440 // main thread so the main looper is set right.
3441 if (data.appInfo.targetSdkVersion <= 12) {
3442 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
3443 }
3444
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003445 /*
3446 * Before spawning a new process, reset the time zone to be the system time zone.
3447 * This needs to be done because the system time zone could have changed after the
3448 * the spawning of this process. Without doing this this process would have the incorrect
3449 * system time zone.
3450 */
3451 TimeZone.setDefault(null);
3452
3453 /*
3454 * Initialize the default locale in this process for the reasons we set the time zone.
3455 */
3456 Locale.setDefault(data.config.locale);
3457
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07003458 /*
3459 * Update the system configuration since its preloaded and might not
3460 * reflect configuration changes. The configuration object passed
3461 * in AppBindData can be safely assumed to be up to date
3462 */
3463 Resources.getSystem().updateConfiguration(mConfiguration, null);
3464
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003465 data.info = getPackageInfoNoCheck(data.appInfo);
3466
Dianne Hackborn96e240f2009-07-26 17:42:30 -07003467 /**
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07003468 * For system applications on userdebug/eng builds, log stack
3469 * traces of disk and network access to dropbox for analysis.
3470 */
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07003471 if ((data.appInfo.flags &
3472 (ApplicationInfo.FLAG_SYSTEM |
Brad Fitzpatrick50d66f92010-09-13 21:29:05 -07003473 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
3474 StrictMode.conditionallyEnableDebugLogging();
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07003475 }
3476
3477 /**
Brad Fitzpatrickb6e18412010-10-28 14:50:05 -07003478 * For apps targetting SDK Honeycomb or later, we don't allow
3479 * network usage on the main event loop / UI thread.
3480 *
3481 * Note to those grepping: this is what ultimately throws
3482 * NetworkOnMainThreadException ...
3483 */
3484 if (data.appInfo.targetSdkVersion > 9) {
3485 StrictMode.enableDeathOnNetwork();
3486 }
3487
3488 /**
Dianne Hackborn96e240f2009-07-26 17:42:30 -07003489 * Switch this process to density compatibility mode if needed.
3490 */
3491 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
3492 == 0) {
3493 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
3494 }
Bob Leee5408332009-09-04 18:31:17 -07003495
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003496 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
3497 // XXX should have option to change the port.
3498 Debug.changeDebugPort(8100);
3499 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003500 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003501 + " is waiting for the debugger on port 8100...");
3502
3503 IActivityManager mgr = ActivityManagerNative.getDefault();
3504 try {
3505 mgr.showWaitingForDebugger(mAppThread, true);
3506 } catch (RemoteException ex) {
3507 }
3508
3509 Debug.waitForDebugger();
3510
3511 try {
3512 mgr.showWaitingForDebugger(mAppThread, false);
3513 } catch (RemoteException ex) {
3514 }
3515
3516 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003517 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003518 + " can be debugged on port 8100...");
3519 }
3520 }
3521
Robert Greenwalt434203a2010-10-11 16:00:27 -07003522 /**
3523 * Initialize the default http proxy in this process for the reasons we set the time zone.
3524 */
3525 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);
3526 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b);
3527 try {
3528 ProxyProperties proxyProperties = service.getProxy();
3529 Proxy.setHttpProxySystemProperty(proxyProperties);
3530 } catch (RemoteException e) {}
3531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003532 if (data.instrumentationName != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08003533 ContextImpl appContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003534 appContext.init(data.info, null, this);
3535 InstrumentationInfo ii = null;
3536 try {
3537 ii = appContext.getPackageManager().
3538 getInstrumentationInfo(data.instrumentationName, 0);
3539 } catch (PackageManager.NameNotFoundException e) {
3540 }
3541 if (ii == null) {
3542 throw new RuntimeException(
3543 "Unable to find instrumentation info for: "
3544 + data.instrumentationName);
3545 }
3546
3547 mInstrumentationAppDir = ii.sourceDir;
3548 mInstrumentationAppPackage = ii.packageName;
3549 mInstrumentedAppDir = data.info.getAppDir();
3550
3551 ApplicationInfo instrApp = new ApplicationInfo();
3552 instrApp.packageName = ii.packageName;
3553 instrApp.sourceDir = ii.sourceDir;
3554 instrApp.publicSourceDir = ii.publicSourceDir;
3555 instrApp.dataDir = ii.dataDir;
Kenny Root85387d72010-08-26 10:13:11 -07003556 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003557 LoadedApk pi = getPackageInfo(instrApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003558 appContext.getClassLoader(), false, true);
Dianne Hackborn21556372010-02-04 16:34:40 -08003559 ContextImpl instrContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003560 instrContext.init(pi, null, this);
3561
3562 try {
3563 java.lang.ClassLoader cl = instrContext.getClassLoader();
3564 mInstrumentation = (Instrumentation)
3565 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
3566 } catch (Exception e) {
3567 throw new RuntimeException(
3568 "Unable to instantiate instrumentation "
3569 + data.instrumentationName + ": " + e.toString(), e);
3570 }
3571
3572 mInstrumentation.init(this, instrContext, appContext,
3573 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
3574
3575 if (data.profileFile != null && !ii.handleProfiling) {
3576 data.handlingProfiling = true;
3577 File file = new File(data.profileFile);
3578 file.getParentFile().mkdirs();
3579 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
3580 }
3581
3582 try {
3583 mInstrumentation.onCreate(data.instrumentationArgs);
3584 }
3585 catch (Exception e) {
3586 throw new RuntimeException(
3587 "Exception thrown in onCreate() of "
3588 + data.instrumentationName + ": " + e.toString(), e);
3589 }
3590
3591 } else {
3592 mInstrumentation = new Instrumentation();
3593 }
3594
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08003595 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
Dianne Hackbornde398512011-01-18 18:45:21 -08003596 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08003597 }
3598
Christopher Tate181fafa2009-05-14 11:12:14 -07003599 // If the app is being launched for full backup or restore, bring it up in
3600 // a restricted environment with the base application class.
Dianne Hackborn0be1f782009-11-09 12:30:12 -08003601 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003602 mInitialApplication = app;
3603
3604 List<ProviderInfo> providers = data.providers;
3605 if (providers != null) {
3606 installContentProviders(app, providers);
Dianne Hackborn3b81bc12011-01-15 11:50:52 -08003607 // For process that contains content providers, we want to
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08003608 // ensure that the JIT is enabled "at some point".
3609 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003610 }
3611
3612 try {
3613 mInstrumentation.callApplicationOnCreate(app);
3614 } catch (Exception e) {
3615 if (!mInstrumentation.onException(app, e)) {
3616 throw new RuntimeException(
3617 "Unable to create application " + app.getClass().getName()
3618 + ": " + e.toString(), e);
3619 }
3620 }
3621 }
3622
3623 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
3624 IActivityManager am = ActivityManagerNative.getDefault();
3625 if (mBoundApplication.profileFile != null && mBoundApplication.handlingProfiling) {
3626 Debug.stopMethodTracing();
3627 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003628 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003629 // + ", app thr: " + mAppThread);
3630 try {
3631 am.finishInstrumentation(mAppThread, resultCode, results);
3632 } catch (RemoteException ex) {
3633 }
3634 }
3635
3636 private final void installContentProviders(
3637 Context context, List<ProviderInfo> providers) {
3638 final ArrayList<IActivityManager.ContentProviderHolder> results =
3639 new ArrayList<IActivityManager.ContentProviderHolder>();
3640
3641 Iterator<ProviderInfo> i = providers.iterator();
3642 while (i.hasNext()) {
3643 ProviderInfo cpi = i.next();
3644 StringBuilder buf = new StringBuilder(128);
Dianne Hackborncef65ee2010-09-30 18:27:22 -07003645 buf.append("Pub ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003646 buf.append(cpi.authority);
3647 buf.append(": ");
3648 buf.append(cpi.name);
3649 Log.i(TAG, buf.toString());
3650 IContentProvider cp = installProvider(context, null, cpi, false);
3651 if (cp != null) {
3652 IActivityManager.ContentProviderHolder cph =
3653 new IActivityManager.ContentProviderHolder(cpi);
3654 cph.provider = cp;
3655 results.add(cph);
3656 // Don't ever unload this provider from the process.
3657 synchronized(mProviderMap) {
3658 mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
3659 }
3660 }
3661 }
3662
3663 try {
3664 ActivityManagerNative.getDefault().publishContentProviders(
3665 getApplicationThread(), results);
3666 } catch (RemoteException ex) {
3667 }
3668 }
3669
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003670 private final IContentProvider getExistingProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003671 synchronized(mProviderMap) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003672 final ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003673 if (pr != null) {
3674 return pr.mProvider;
3675 }
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003676 return null;
3677 }
3678 }
3679
3680 private final IContentProvider getProvider(Context context, String name) {
3681 IContentProvider existing = getExistingProvider(context, name);
3682 if (existing != null) {
3683 return existing;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003684 }
3685
3686 IActivityManager.ContentProviderHolder holder = null;
3687 try {
3688 holder = ActivityManagerNative.getDefault().getContentProvider(
3689 getApplicationThread(), name);
3690 } catch (RemoteException ex) {
3691 }
3692 if (holder == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003693 Slog.e(TAG, "Failed to find provider info for " + name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003694 return null;
3695 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696
3697 IContentProvider prov = installProvider(context, holder.provider,
3698 holder.info, true);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003699 //Slog.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003700 if (holder.noReleaseNeeded || holder.provider == null) {
3701 // We are not going to release the provider if it is an external
3702 // provider that doesn't care about being released, or if it is
3703 // a local provider running in this process.
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003704 //Slog.i(TAG, "*** NO RELEASE NEEDED");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 synchronized(mProviderMap) {
3706 mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(10000));
3707 }
3708 }
3709 return prov;
3710 }
3711
3712 public final IContentProvider acquireProvider(Context c, String name) {
3713 IContentProvider provider = getProvider(c, name);
3714 if(provider == null)
3715 return null;
3716 IBinder jBinder = provider.asBinder();
3717 synchronized(mProviderMap) {
3718 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3719 if(prc == null) {
3720 mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
3721 } else {
3722 prc.count++;
3723 } //end else
3724 } //end synchronized
3725 return provider;
3726 }
3727
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003728 public final IContentProvider acquireExistingProvider(Context c, String name) {
3729 IContentProvider provider = getExistingProvider(c, name);
3730 if(provider == null)
3731 return null;
3732 IBinder jBinder = provider.asBinder();
3733 synchronized(mProviderMap) {
3734 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3735 if(prc == null) {
3736 mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
3737 } else {
3738 prc.count++;
3739 } //end else
3740 } //end synchronized
3741 return provider;
3742 }
3743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003744 public final boolean releaseProvider(IContentProvider provider) {
3745 if(provider == null) {
3746 return false;
3747 }
3748 IBinder jBinder = provider.asBinder();
3749 synchronized(mProviderMap) {
3750 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3751 if(prc == null) {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003752 if(localLOGV) Slog.v(TAG, "releaseProvider::Weird shouldn't be here");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003753 return false;
3754 } else {
3755 prc.count--;
3756 if(prc.count == 0) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003757 // Schedule the actual remove asynchronously, since we
3758 // don't know the context this will be called in.
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003759 // TODO: it would be nice to post a delayed message, so
3760 // if we come back and need the same provider quickly
3761 // we will still have it available.
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003762 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, provider);
3763 mH.sendMessage(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003764 } //end if
3765 } //end else
3766 } //end synchronized
3767 return true;
3768 }
3769
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003770 final void completeRemoveProvider(IContentProvider provider) {
3771 IBinder jBinder = provider.asBinder();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003772 String name = null;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003773 synchronized(mProviderMap) {
3774 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3775 if(prc != null && prc.count == 0) {
3776 mProviderRefCountMap.remove(jBinder);
3777 //invoke removeProvider to dereference provider
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003778 name = removeProviderLocked(provider);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003779 }
3780 }
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003781
3782 if (name != null) {
3783 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003784 if(localLOGV) Slog.v(TAG, "removeProvider::Invoking " +
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003785 "ActivityManagerNative.removeContentProvider(" + name);
3786 ActivityManagerNative.getDefault().removeContentProvider(
3787 getApplicationThread(), name);
3788 } catch (RemoteException e) {
3789 //do nothing content provider object is dead any way
3790 } //end catch
3791 }
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003792 }
3793
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003794 public final String removeProviderLocked(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003795 if (provider == null) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003796 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003797 }
3798 IBinder providerBinder = provider.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003799
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003800 String name = null;
3801
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003802 // remove the provider from mProviderMap
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003803 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003804 while (iter.hasNext()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003805 ProviderClientRecord pr = iter.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003806 IBinder myBinder = pr.mProvider.asBinder();
3807 if (myBinder == providerBinder) {
3808 //find if its published by this process itself
3809 if(pr.mLocalProvider != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003810 if(localLOGV) Slog.i(TAG, "removeProvider::found local provider returning");
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003811 return name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003812 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003813 if(localLOGV) Slog.v(TAG, "removeProvider::Not local provider Unlinking " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003814 "death recipient");
3815 //content provider is in another process
3816 myBinder.unlinkToDeath(pr, 0);
3817 iter.remove();
3818 //invoke remove only once for the very first name seen
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003819 if(name == null) {
3820 name = pr.mName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003821 }
3822 } //end if myBinder
3823 } //end while iter
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003824
3825 return name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003826 }
3827
3828 final void removeDeadProvider(String name, IContentProvider provider) {
3829 synchronized(mProviderMap) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003830 ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003831 if (pr.mProvider.asBinder() == provider.asBinder()) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003832 Slog.i(TAG, "Removing dead content provider: " + name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003833 ProviderClientRecord removed = mProviderMap.remove(name);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07003834 if (removed != null) {
3835 removed.mProvider.asBinder().unlinkToDeath(removed, 0);
3836 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003837 }
3838 }
3839 }
3840
3841 final void removeDeadProviderLocked(String name, IContentProvider provider) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003842 ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003843 if (pr.mProvider.asBinder() == provider.asBinder()) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003844 Slog.i(TAG, "Removing dead content provider: " + name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003845 ProviderClientRecord removed = mProviderMap.remove(name);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07003846 if (removed != null) {
3847 removed.mProvider.asBinder().unlinkToDeath(removed, 0);
3848 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003849 }
3850 }
3851
3852 private final IContentProvider installProvider(Context context,
3853 IContentProvider provider, ProviderInfo info, boolean noisy) {
3854 ContentProvider localProvider = null;
3855 if (provider == null) {
3856 if (noisy) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003857 Slog.d(TAG, "Loading provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003858 + info.name);
3859 }
3860 Context c = null;
3861 ApplicationInfo ai = info.applicationInfo;
3862 if (context.getPackageName().equals(ai.packageName)) {
3863 c = context;
3864 } else if (mInitialApplication != null &&
3865 mInitialApplication.getPackageName().equals(ai.packageName)) {
3866 c = mInitialApplication;
3867 } else {
3868 try {
3869 c = context.createPackageContext(ai.packageName,
3870 Context.CONTEXT_INCLUDE_CODE);
3871 } catch (PackageManager.NameNotFoundException e) {
3872 }
3873 }
3874 if (c == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003875 Slog.w(TAG, "Unable to get context for package " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003876 ai.packageName +
3877 " while loading content provider " +
3878 info.name);
3879 return null;
3880 }
3881 try {
3882 final java.lang.ClassLoader cl = c.getClassLoader();
3883 localProvider = (ContentProvider)cl.
3884 loadClass(info.name).newInstance();
3885 provider = localProvider.getIContentProvider();
3886 if (provider == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003887 Slog.e(TAG, "Failed to instantiate class " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003888 info.name + " from sourceDir " +
3889 info.applicationInfo.sourceDir);
3890 return null;
3891 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003892 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003893 TAG, "Instantiating local provider " + info.name);
3894 // XXX Need to create the correct context for this provider.
3895 localProvider.attachInfo(c, info);
3896 } catch (java.lang.Exception e) {
3897 if (!mInstrumentation.onException(null, e)) {
3898 throw new RuntimeException(
3899 "Unable to get provider " + info.name
3900 + ": " + e.toString(), e);
3901 }
3902 return null;
3903 }
3904 } else if (localLOGV) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003905 Slog.v(TAG, "Installing external provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003906 + info.name);
3907 }
3908
3909 synchronized (mProviderMap) {
3910 // Cache the pointer for the remote provider.
3911 String names[] = PATTERN_SEMICOLON.split(info.authority);
3912 for (int i=0; i<names.length; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003913 ProviderClientRecord pr = new ProviderClientRecord(names[i], provider,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003914 localProvider);
3915 try {
3916 provider.asBinder().linkToDeath(pr, 0);
3917 mProviderMap.put(names[i], pr);
3918 } catch (RemoteException e) {
3919 return null;
3920 }
3921 }
3922 if (localProvider != null) {
3923 mLocalProviders.put(provider.asBinder(),
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003924 new ProviderClientRecord(null, provider, localProvider));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003925 }
3926 }
3927
3928 return provider;
3929 }
3930
3931 private final void attach(boolean system) {
3932 sThreadLocal.set(this);
3933 mSystemThread = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003934 if (!system) {
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08003935 ViewRoot.addFirstDrawHandler(new Runnable() {
3936 public void run() {
3937 ensureJitEnabled();
3938 }
3939 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003940 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
3941 RuntimeInit.setApplicationObject(mAppThread.asBinder());
3942 IActivityManager mgr = ActivityManagerNative.getDefault();
3943 try {
3944 mgr.attachApplication(mAppThread);
3945 } catch (RemoteException ex) {
3946 }
3947 } else {
3948 // Don't set application object here -- if the system crashes,
3949 // we can't display an alert, we just want to die die die.
3950 android.ddm.DdmHandleAppName.setAppName("system_process");
3951 try {
3952 mInstrumentation = new Instrumentation();
Dianne Hackborn21556372010-02-04 16:34:40 -08003953 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003954 context.init(getSystemContext().mPackageInfo, null, this);
3955 Application app = Instrumentation.newApplication(Application.class, context);
3956 mAllApplications.add(app);
3957 mInitialApplication = app;
3958 app.onCreate();
3959 } catch (Exception e) {
3960 throw new RuntimeException(
3961 "Unable to instantiate Application():" + e.toString(), e);
3962 }
3963 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003964
3965 ViewRoot.addConfigCallback(new ComponentCallbacks() {
3966 public void onConfigurationChanged(Configuration newConfig) {
3967 synchronized (mPackages) {
Dianne Hackbornae078162010-03-18 11:29:37 -07003968 // We need to apply this change to the resources
3969 // immediately, because upon returning the view
3970 // hierarchy will be informed about it.
3971 if (applyConfigurationToResourcesLocked(newConfig)) {
3972 // This actually changed the resources! Tell
3973 // everyone about it.
3974 if (mPendingConfiguration == null ||
3975 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
3976 mPendingConfiguration = newConfig;
3977
3978 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
3979 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003980 }
3981 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003982 }
3983 public void onLowMemory() {
3984 }
3985 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003986 }
3987
3988 private final void detach()
3989 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003990 sThreadLocal.set(null);
3991 }
3992
3993 public static final ActivityThread systemMain() {
Romain Guy52339202010-09-03 16:04:46 -07003994 HardwareRenderer.disable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003995 ActivityThread thread = new ActivityThread();
3996 thread.attach(true);
3997 return thread;
3998 }
3999
4000 public final void installSystemProviders(List providers) {
4001 if (providers != null) {
4002 installContentProviders(mInitialApplication,
4003 (List<ProviderInfo>)providers);
4004 }
4005 }
4006
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004007 public int getIntCoreSetting(String key, int defaultValue) {
Svetoslav Ganov9aa597e2011-03-03 18:17:41 -08004008 synchronized (mPackages) {
4009 if (mCoreSettings != null) {
4010 return mCoreSettings.getInt(key, defaultValue);
Svetoslav Ganov54d068e2011-03-02 12:58:40 -08004011 } else {
4012 return defaultValue;
4013 }
4014 }
4015 }
4016
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004017 public static final void main(String[] args) {
Bob Leee5408332009-09-04 18:31:17 -07004018 SamplingProfilerIntegration.start();
4019
Brad Fitzpatrick4d9e6d22010-11-15 08:49:51 -08004020 // CloseGuard defaults to true and can be quite spammy. We
4021 // disable it here, but selectively enable it later (via
4022 // StrictMode) on debug builds, but using DropBox, not logs.
4023 CloseGuard.setEnabled(false);
4024
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004025 Process.setArgV0("<pre-initialized>");
4026
4027 Looper.prepareMainLooper();
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07004028 if (sMainThreadHandler == null) {
4029 sMainThreadHandler = new Handler();
4030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004031
4032 ActivityThread thread = new ActivityThread();
4033 thread.attach(false);
4034
Dianne Hackborn287952c2010-09-22 22:34:31 -07004035 if (false) {
4036 Looper.myLooper().setMessageLogging(new
4037 LogPrinter(Log.DEBUG, "ActivityThread"));
4038 }
4039
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004040 Looper.loop();
4041
4042 if (Process.supportsProcesses()) {
4043 throw new RuntimeException("Main thread loop unexpectedly exited");
4044 }
4045
4046 thread.detach();
Bob Leeeec2f412009-09-10 11:01:24 +02004047 String name = (thread.mInitialApplication != null)
4048 ? thread.mInitialApplication.getPackageName()
4049 : "<unknown>";
Dianne Hackborn399cccb2010-04-13 22:57:49 -07004050 Slog.i(TAG, "Main thread of " + name + " is now exiting");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004051 }
4052}