blob: b8bbc88fd43f753f8e46525724e59b09e4c90dc8 [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;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -070045import android.os.Build;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080046import android.os.Bundle;
47import android.os.Debug;
48import android.os.Handler;
49import android.os.IBinder;
50import android.os.Looper;
51import android.os.Message;
52import android.os.MessageQueue;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070053import android.os.ParcelFileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.Process;
55import android.os.RemoteException;
56import android.os.ServiceManager;
Brad Fitzpatrick438d0592010-06-10 12:19:19 -070057import android.os.StrictMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058import android.os.SystemClock;
59import android.util.AndroidRuntimeException;
60import android.util.Config;
61import android.util.DisplayMetrics;
62import android.util.EventLog;
63import android.util.Log;
Dianne Hackborn287952c2010-09-22 22:34:31 -070064import android.util.LogPrinter;
Dianne Hackbornc9421ba2010-03-11 22:23:46 -080065import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.view.Display;
Romain Guy52339202010-09-03 16:04:46 -070067import android.view.HardwareRenderer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import android.view.View;
69import android.view.ViewDebug;
70import android.view.ViewManager;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -080071import android.view.ViewRoot;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072import android.view.Window;
73import android.view.WindowManager;
74import android.view.WindowManagerImpl;
75
76import com.android.internal.os.BinderInternal;
77import com.android.internal.os.RuntimeInit;
Bob Leee5408332009-09-04 18:31:17 -070078import com.android.internal.os.SamplingProfilerIntegration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079
Romain Guya14c8e02010-09-03 16:51:54 -070080import dalvik.system.VMDebug;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080081import org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl;
82
83import java.io.File;
84import java.io.FileDescriptor;
85import java.io.FileOutputStream;
Dianne Hackborn9c8dd552009-06-23 19:22:52 -070086import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import java.io.PrintWriter;
88import java.lang.ref.WeakReference;
89import java.util.ArrayList;
90import java.util.HashMap;
91import java.util.Iterator;
92import java.util.List;
93import java.util.Locale;
94import java.util.Map;
95import java.util.TimeZone;
96import java.util.regex.Pattern;
97
Bob Leee5408332009-09-04 18:31:17 -070098import dalvik.system.SamplingProfiler;
99
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800100final class SuperNotCalledException extends AndroidRuntimeException {
101 public SuperNotCalledException(String msg) {
102 super(msg);
103 }
104}
105
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700106final class RemoteServiceException extends AndroidRuntimeException {
107 public RemoteServiceException(String msg) {
108 super(msg);
109 }
110}
111
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112/**
113 * This manages the execution of the main thread in an
114 * application process, scheduling and executing activities,
115 * broadcasts, and other operations on it as the activity
116 * manager requests.
117 *
118 * {@hide}
119 */
120public final class ActivityThread {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700121 static final String TAG = "ActivityThread";
Jim Miller0b2a6d02010-07-13 18:01:29 -0700122 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 private static final boolean DEBUG = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700124 static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700125 static final boolean DEBUG_MESSAGES = false;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700126 static final boolean DEBUG_BROADCAST = false;
Chris Tate8a7dc172009-03-24 20:11:42 -0700127 private static final boolean DEBUG_RESULTS = false;
Christopher Tate436344a2009-09-30 16:17:37 -0700128 private static final boolean DEBUG_BACKUP = false;
Dianne Hackborndc6b6352009-09-30 14:20:09 -0700129 private static final boolean DEBUG_CONFIGURATION = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 private static final long MIN_TIME_BETWEEN_GCS = 5*1000;
131 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";");
132 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003;
133 private static final int LOG_ON_PAUSE_CALLED = 30021;
134 private static final int LOG_ON_RESUME_CALLED = 30022;
135
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700136 static ContextImpl mSystemContext = null;
Bob Leee5408332009-09-04 18:31:17 -0700137
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700138 static IPackageManager sPackageManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700140 final ApplicationThread mAppThread = new ApplicationThread();
141 final Looper mLooper = Looper.myLooper();
142 final H mH = new H();
143 final HashMap<IBinder, ActivityClientRecord> mActivities
144 = new HashMap<IBinder, ActivityClientRecord>();
145 // List of new activities (via ActivityRecord.nextIdle) that should
146 // be reported when next we idle.
147 ActivityClientRecord mNewActivities = null;
148 // Number of activities that are currently visible on-screen.
149 int mNumVisibleActivities = 0;
150 final HashMap<IBinder, Service> mServices
151 = new HashMap<IBinder, Service>();
152 AppBindData mBoundApplication;
153 Configuration mConfiguration;
154 Configuration mResConfiguration;
155 Application mInitialApplication;
156 final ArrayList<Application> mAllApplications
157 = new ArrayList<Application>();
158 // set of instantiated backup agents, keyed by package name
159 final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700160 static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700161 Instrumentation mInstrumentation;
162 String mInstrumentationAppDir = null;
163 String mInstrumentationAppPackage = null;
164 String mInstrumentedAppDir = null;
165 boolean mSystemThread = false;
166 boolean mJitEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800167
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700168 // These can be accessed by multiple threads; mPackages is the lock.
169 // XXX For now we keep around information about all packages we have
170 // seen, not removing entries from this map.
171 final HashMap<String, WeakReference<LoadedApk>> mPackages
172 = new HashMap<String, WeakReference<LoadedApk>>();
173 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages
174 = new HashMap<String, WeakReference<LoadedApk>>();
175 Display mDisplay = null;
176 DisplayMetrics mDisplayMetrics = null;
177 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources
178 = new HashMap<ResourcesKey, WeakReference<Resources> >();
179 final ArrayList<ActivityClientRecord> mRelaunchingActivities
180 = new ArrayList<ActivityClientRecord>();
181 Configuration mPendingConfiguration = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800182
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700183 // The lock of mProviderMap protects the following variables.
184 final HashMap<String, ProviderClientRecord> mProviderMap
185 = new HashMap<String, ProviderClientRecord>();
186 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap
187 = new HashMap<IBinder, ProviderRefCount>();
188 final HashMap<IBinder, ProviderClientRecord> mLocalProviders
189 = new HashMap<IBinder, ProviderClientRecord>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800190
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700191 final GcIdler mGcIdler = new GcIdler();
192 boolean mGcIdlerScheduled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -0700194 static Handler sMainThreadHandler; // set once in main()
195
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700196 private static final class ActivityClientRecord {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 IBinder token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700198 int ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199 Intent intent;
200 Bundle state;
201 Activity activity;
202 Window window;
203 Activity parent;
204 String embeddedID;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -0700205 Activity.NonConfigurationInstances lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800206 boolean paused;
207 boolean stopped;
208 boolean hideForNow;
209 Configuration newConfig;
Dianne Hackborne88846e2009-09-30 21:34:25 -0700210 Configuration createdConfig;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700211 ActivityClientRecord nextIdle;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800212
213 ActivityInfo activityInfo;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700214 LoadedApk packageInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800215
216 List<ResultInfo> pendingResults;
217 List<Intent> pendingIntents;
218
219 boolean startsNotResumed;
220 boolean isForward;
221
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700222 ActivityClientRecord() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800223 parent = null;
224 embeddedID = null;
225 paused = false;
226 stopped = false;
227 hideForNow = false;
228 nextIdle = null;
229 }
230
231 public String toString() {
232 ComponentName componentName = intent.getComponent();
233 return "ActivityRecord{"
234 + Integer.toHexString(System.identityHashCode(this))
235 + " token=" + token + " " + (componentName == null
236 ? "no component name" : componentName.toShortString())
237 + "}";
238 }
239 }
240
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700241 private final class ProviderClientRecord implements IBinder.DeathRecipient {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 final String mName;
243 final IContentProvider mProvider;
244 final ContentProvider mLocalProvider;
245
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700246 ProviderClientRecord(String name, IContentProvider provider,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247 ContentProvider localProvider) {
248 mName = name;
249 mProvider = provider;
250 mLocalProvider = localProvider;
251 }
252
253 public void binderDied() {
254 removeDeadProvider(mName, mProvider);
255 }
256 }
257
258 private static final class NewIntentData {
259 List<Intent> intents;
260 IBinder token;
261 public String toString() {
262 return "NewIntentData{intents=" + intents + " token=" + token + "}";
263 }
264 }
265
266 private static final class ReceiverData {
267 Intent intent;
268 ActivityInfo info;
269 int resultCode;
270 String resultData;
271 Bundle resultExtras;
272 boolean sync;
273 boolean resultAbort;
274 public String toString() {
275 return "ReceiverData{intent=" + intent + " packageName=" +
276 info.packageName + " resultCode=" + resultCode
277 + " resultData=" + resultData + " resultExtras=" + resultExtras + "}";
278 }
279 }
280
Christopher Tate181fafa2009-05-14 11:12:14 -0700281 private static final class CreateBackupAgentData {
282 ApplicationInfo appInfo;
283 int backupMode;
284 public String toString() {
285 return "CreateBackupAgentData{appInfo=" + appInfo
286 + " backupAgent=" + appInfo.backupAgentName
287 + " mode=" + backupMode + "}";
288 }
289 }
Bob Leee5408332009-09-04 18:31:17 -0700290
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291 private static final class CreateServiceData {
292 IBinder token;
293 ServiceInfo info;
294 Intent intent;
295 public String toString() {
296 return "CreateServiceData{token=" + token + " className="
297 + info.name + " packageName=" + info.packageName
298 + " intent=" + intent + "}";
299 }
300 }
301
302 private static final class BindServiceData {
303 IBinder token;
304 Intent intent;
305 boolean rebind;
306 public String toString() {
307 return "BindServiceData{token=" + token + " intent=" + intent + "}";
308 }
309 }
310
311 private static final class ServiceArgsData {
312 IBinder token;
313 int startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700314 int flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315 Intent args;
316 public String toString() {
317 return "ServiceArgsData{token=" + token + " startId=" + startId
318 + " args=" + args + "}";
319 }
320 }
321
322 private static final class AppBindData {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700323 LoadedApk info;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800324 String processName;
325 ApplicationInfo appInfo;
326 List<ProviderInfo> providers;
327 ComponentName instrumentationName;
328 String profileFile;
329 Bundle instrumentationArgs;
330 IInstrumentationWatcher instrumentationWatcher;
331 int debugMode;
Christopher Tate181fafa2009-05-14 11:12:14 -0700332 boolean restrictedBackupMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800333 Configuration config;
334 boolean handlingProfiling;
335 public String toString() {
336 return "AppBindData{appInfo=" + appInfo + "}";
337 }
338 }
339
Dianne Hackborn625ac272010-09-17 18:29:22 -0700340 private static final class DumpComponentInfo {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 FileDescriptor fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700342 IBinder token;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 String[] args;
344 boolean dumped;
345 }
346
347 private static final class ResultData {
348 IBinder token;
349 List<ResultInfo> results;
350 public String toString() {
351 return "ResultData{token=" + token + " results" + results + "}";
352 }
353 }
354
355 private static final class ContextCleanupInfo {
Dianne Hackborn21556372010-02-04 16:34:40 -0800356 ContextImpl context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 String what;
358 String who;
359 }
360
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700361 private static final class ProfilerControlData {
362 String path;
363 ParcelFileDescriptor fd;
364 }
365
Andy McFadden824c5102010-07-09 16:26:57 -0700366 private static final class DumpHeapData {
367 String path;
368 ParcelFileDescriptor fd;
369 }
370
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800371 private final class ApplicationThread extends ApplicationThreadNative {
372 private static final String HEAP_COLUMN = "%17s %8s %8s %8s %8s";
373 private static final String ONE_COUNT_COLUMN = "%17s %8d";
374 private static final String TWO_COUNT_COLUMNS = "%17s %8d %17s %8d";
Vasu Nori3c7131f2010-09-21 14:36:57 -0700375 private static final String TWO_COUNT_COLUMNS_DB = "%20s %8d %20s %8d";
376 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s";
Bob Leee5408332009-09-04 18:31:17 -0700377
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 // Formatting for checkin service - update version if row format changes
379 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 1;
Bob Leee5408332009-09-04 18:31:17 -0700380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 public final void schedulePauseActivity(IBinder token, boolean finished,
382 boolean userLeaving, int configChanges) {
383 queueOrSendMessage(
384 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY,
385 token,
386 (userLeaving ? 1 : 0),
387 configChanges);
388 }
389
390 public final void scheduleStopActivity(IBinder token, boolean showWindow,
391 int configChanges) {
392 queueOrSendMessage(
393 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE,
394 token, 0, configChanges);
395 }
396
397 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) {
398 queueOrSendMessage(
399 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW,
400 token);
401 }
402
403 public final void scheduleResumeActivity(IBinder token, boolean isForward) {
404 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
405 }
406
407 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) {
408 ResultData res = new ResultData();
409 res.token = token;
410 res.results = results;
411 queueOrSendMessage(H.SEND_RESULT, res);
412 }
413
414 // we use token to identify this activity without having to send the
415 // activity itself back to the activity manager. (matters more with ipc)
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700416 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800417 ActivityInfo info, Bundle state, List<ResultInfo> pendingResults,
418 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700419 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800420
421 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -0700422 r.ident = ident;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800423 r.intent = intent;
424 r.activityInfo = info;
425 r.state = state;
426
427 r.pendingResults = pendingResults;
428 r.pendingIntents = pendingNewIntents;
429
430 r.startsNotResumed = notResumed;
431 r.isForward = isForward;
432
433 queueOrSendMessage(H.LAUNCH_ACTIVITY, r);
434 }
435
436 public final void scheduleRelaunchActivity(IBinder token,
437 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents,
Dianne Hackborn871ecdc2009-12-11 15:24:33 -0800438 int configChanges, boolean notResumed, Configuration config) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700439 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440
441 r.token = token;
442 r.pendingResults = pendingResults;
443 r.pendingIntents = pendingNewIntents;
444 r.startsNotResumed = notResumed;
Dianne Hackborn871ecdc2009-12-11 15:24:33 -0800445 r.createdConfig = config;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800446
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800447 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800448 mRelaunchingActivities.add(r);
449 }
Bob Leee5408332009-09-04 18:31:17 -0700450
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800451 queueOrSendMessage(H.RELAUNCH_ACTIVITY, r, configChanges);
452 }
453
454 public final void scheduleNewIntent(List<Intent> intents, IBinder token) {
455 NewIntentData data = new NewIntentData();
456 data.intents = intents;
457 data.token = token;
458
459 queueOrSendMessage(H.NEW_INTENT, data);
460 }
461
462 public final void scheduleDestroyActivity(IBinder token, boolean finishing,
463 int configChanges) {
464 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0,
465 configChanges);
466 }
467
468 public final void scheduleReceiver(Intent intent, ActivityInfo info,
469 int resultCode, String data, Bundle extras, boolean sync) {
470 ReceiverData r = new ReceiverData();
471
472 r.intent = intent;
473 r.info = info;
474 r.resultCode = resultCode;
475 r.resultData = data;
476 r.resultExtras = extras;
477 r.sync = sync;
478
479 queueOrSendMessage(H.RECEIVER, r);
480 }
481
Christopher Tate181fafa2009-05-14 11:12:14 -0700482 public final void scheduleCreateBackupAgent(ApplicationInfo app, int backupMode) {
483 CreateBackupAgentData d = new CreateBackupAgentData();
484 d.appInfo = app;
485 d.backupMode = backupMode;
486
487 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d);
488 }
489
490 public final void scheduleDestroyBackupAgent(ApplicationInfo app) {
491 CreateBackupAgentData d = new CreateBackupAgentData();
492 d.appInfo = app;
493
494 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d);
495 }
496
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800497 public final void scheduleCreateService(IBinder token,
498 ServiceInfo info) {
499 CreateServiceData s = new CreateServiceData();
500 s.token = token;
501 s.info = info;
502
503 queueOrSendMessage(H.CREATE_SERVICE, s);
504 }
505
506 public final void scheduleBindService(IBinder token, Intent intent,
507 boolean rebind) {
508 BindServiceData s = new BindServiceData();
509 s.token = token;
510 s.intent = intent;
511 s.rebind = rebind;
512
513 queueOrSendMessage(H.BIND_SERVICE, s);
514 }
515
516 public final void scheduleUnbindService(IBinder token, Intent intent) {
517 BindServiceData s = new BindServiceData();
518 s.token = token;
519 s.intent = intent;
520
521 queueOrSendMessage(H.UNBIND_SERVICE, s);
522 }
523
524 public final void scheduleServiceArgs(IBinder token, int startId,
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700525 int flags ,Intent args) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800526 ServiceArgsData s = new ServiceArgsData();
527 s.token = token;
528 s.startId = startId;
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -0700529 s.flags = flags;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800530 s.args = args;
531
532 queueOrSendMessage(H.SERVICE_ARGS, s);
533 }
534
535 public final void scheduleStopService(IBinder token) {
536 queueOrSendMessage(H.STOP_SERVICE, token);
537 }
538
539 public final void bindApplication(String processName,
540 ApplicationInfo appInfo, List<ProviderInfo> providers,
541 ComponentName instrumentationName, String profileFile,
542 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
Christopher Tate181fafa2009-05-14 11:12:14 -0700543 int debugMode, boolean isRestrictedBackupMode, Configuration config,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800544 Map<String, IBinder> services) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545
546 if (services != null) {
547 // Setup the service cache in the ServiceManager
548 ServiceManager.initServiceCache(services);
549 }
550
551 AppBindData data = new AppBindData();
552 data.processName = processName;
553 data.appInfo = appInfo;
554 data.providers = providers;
555 data.instrumentationName = instrumentationName;
556 data.profileFile = profileFile;
557 data.instrumentationArgs = instrumentationArgs;
558 data.instrumentationWatcher = instrumentationWatcher;
559 data.debugMode = debugMode;
Christopher Tate181fafa2009-05-14 11:12:14 -0700560 data.restrictedBackupMode = isRestrictedBackupMode;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800561 data.config = config;
562 queueOrSendMessage(H.BIND_APPLICATION, data);
563 }
564
565 public final void scheduleExit() {
566 queueOrSendMessage(H.EXIT_APPLICATION, null);
567 }
568
Christopher Tate5e1ab332009-09-01 20:32:49 -0700569 public final void scheduleSuicide() {
570 queueOrSendMessage(H.SUICIDE, null);
571 }
572
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800573 public void requestThumbnail(IBinder token) {
574 queueOrSendMessage(H.REQUEST_THUMBNAIL, token);
575 }
576
577 public void scheduleConfigurationChanged(Configuration config) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -0800578 synchronized (mPackages) {
579 if (mPendingConfiguration == null ||
580 mPendingConfiguration.isOtherSeqNewer(config)) {
581 mPendingConfiguration = config;
582 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800583 }
584 queueOrSendMessage(H.CONFIGURATION_CHANGED, config);
585 }
586
587 public void updateTimeZone() {
588 TimeZone.setDefault(null);
589 }
590
591 public void processInBackground() {
592 mH.removeMessages(H.GC_WHEN_IDLE);
593 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE));
594 }
595
596 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) {
Dianne Hackborn625ac272010-09-17 18:29:22 -0700597 DumpComponentInfo data = new DumpComponentInfo();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 data.fd = fd;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700599 data.token = servicetoken;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800600 data.args = args;
601 data.dumped = false;
602 queueOrSendMessage(H.DUMP_SERVICE, data);
603 synchronized (data) {
604 while (!data.dumped) {
605 try {
606 data.wait();
607 } catch (InterruptedException e) {
608 // no need to do anything here, we will keep waiting until
609 // dumped is set
610 }
611 }
612 }
613 }
614
615 // This function exists to make sure all receiver dispatching is
616 // correctly ordered, since these are one-way calls and the binder driver
617 // applies transaction ordering per object for such calls.
618 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
Dianne Hackborn68d881c2009-10-05 13:58:17 -0700619 int resultCode, String dataStr, Bundle extras, boolean ordered,
620 boolean sticky) throws RemoteException {
621 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 }
Bob Leee5408332009-09-04 18:31:17 -0700623
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800624 public void scheduleLowMemory() {
625 queueOrSendMessage(H.LOW_MEMORY, null);
626 }
627
628 public void scheduleActivityConfigurationChanged(IBinder token) {
629 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token);
630 }
631
Dianne Hackborn9c8dd552009-06-23 19:22:52 -0700632 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd) {
633 ProfilerControlData pcd = new ProfilerControlData();
634 pcd.path = path;
635 pcd.fd = fd;
636 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800637 }
638
Andy McFadden824c5102010-07-09 16:26:57 -0700639 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) {
640 DumpHeapData dhd = new DumpHeapData();
641 dhd.path = path;
642 dhd.fd = fd;
643 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0);
644 }
645
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700646 public void setSchedulingGroup(int group) {
647 // Note: do this immediately, since going into the foreground
648 // should happen regardless of what pending work we have to do
649 // and the activity manager will wait for us to report back that
650 // we are done before sending us to the background.
651 try {
652 Process.setProcessGroup(Process.myPid(), group);
653 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -0800654 Slog.w(TAG, "Failed setting process group to " + group, e);
Dianne Hackborn06de2ea2009-05-21 12:56:43 -0700655 }
656 }
Bob Leee5408332009-09-04 18:31:17 -0700657
Dianne Hackborn3025ef32009-08-31 21:31:47 -0700658 public void getMemoryInfo(Debug.MemoryInfo outInfo) {
659 Debug.getMemoryInfo(outInfo);
660 }
Bob Leee5408332009-09-04 18:31:17 -0700661
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700662 public void dispatchPackageBroadcast(int cmd, String[] packages) {
663 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd);
664 }
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700665
666 public void scheduleCrash(String msg) {
667 queueOrSendMessage(H.SCHEDULE_CRASH, msg);
668 }
Dianne Hackborn625ac272010-09-17 18:29:22 -0700669
670 public void dumpActivity(FileDescriptor fd, IBinder activitytoken, String[] args) {
671 DumpComponentInfo data = new DumpComponentInfo();
672 data.fd = fd;
673 data.token = activitytoken;
674 data.args = args;
675 data.dumped = false;
676 queueOrSendMessage(H.DUMP_ACTIVITY, data);
677 synchronized (data) {
678 while (!data.dumped) {
679 try {
680 data.wait();
681 } catch (InterruptedException e) {
682 // no need to do anything here, we will keep waiting until
683 // dumped is set
684 }
685 }
686 }
687 }
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700688
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800689 @Override
690 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
691 long nativeMax = Debug.getNativeHeapSize() / 1024;
692 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
693 long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
694
695 Debug.MemoryInfo memInfo = new Debug.MemoryInfo();
696 Debug.getMemoryInfo(memInfo);
697
698 final int nativeShared = memInfo.nativeSharedDirty;
699 final int dalvikShared = memInfo.dalvikSharedDirty;
700 final int otherShared = memInfo.otherSharedDirty;
701
702 final int nativePrivate = memInfo.nativePrivateDirty;
703 final int dalvikPrivate = memInfo.dalvikPrivateDirty;
704 final int otherPrivate = memInfo.otherPrivateDirty;
705
706 Runtime runtime = Runtime.getRuntime();
707
708 long dalvikMax = runtime.totalMemory() / 1024;
709 long dalvikFree = runtime.freeMemory() / 1024;
710 long dalvikAllocated = dalvikMax - dalvikFree;
711 long viewInstanceCount = ViewDebug.getViewInstanceCount();
712 long viewRootInstanceCount = ViewDebug.getViewRootInstanceCount();
Romain Guya14c8e02010-09-03 16:51:54 -0700713 long appContextInstanceCount = VMDebug.countInstancesOfClass(ContextImpl.class);
714 long activityInstanceCount = VMDebug.countInstancesOfClass(Activity.class);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800715 int globalAssetCount = AssetManager.getGlobalAssetCount();
716 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount();
717 int binderLocalObjectCount = Debug.getBinderLocalObjectCount();
718 int binderProxyObjectCount = Debug.getBinderProxyObjectCount();
719 int binderDeathObjectCount = Debug.getBinderDeathObjectCount();
720 int openSslSocketCount = OpenSSLSocketImpl.getInstanceCount();
721 long sqliteAllocated = SQLiteDebug.getHeapAllocatedSize() / 1024;
Vasu Noric3849202010-03-09 10:47:25 -0800722 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo();
Bob Leee5408332009-09-04 18:31:17 -0700723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800724 // Check to see if we were called by checkin server. If so, print terse format.
725 boolean doCheckinFormat = false;
726 if (args != null) {
727 for (String arg : args) {
728 if ("-c".equals(arg)) doCheckinFormat = true;
729 }
730 }
Bob Leee5408332009-09-04 18:31:17 -0700731
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800732 // For checkin, we print one long comma-separated list of values
733 if (doCheckinFormat) {
734 // NOTE: if you change anything significant below, also consider changing
735 // ACTIVITY_THREAD_CHECKIN_VERSION.
Bob Leee5408332009-09-04 18:31:17 -0700736 String processName = (mBoundApplication != null)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 ? mBoundApplication.processName : "unknown";
Bob Leee5408332009-09-04 18:31:17 -0700738
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 // Header
740 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(',');
741 pw.print(Process.myPid()); pw.print(',');
742 pw.print(processName); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700743
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800744 // Heap info - max
745 pw.print(nativeMax); pw.print(',');
746 pw.print(dalvikMax); pw.print(',');
747 pw.print("N/A,");
748 pw.print(nativeMax + dalvikMax); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700749
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800750 // Heap info - allocated
751 pw.print(nativeAllocated); pw.print(',');
752 pw.print(dalvikAllocated); pw.print(',');
753 pw.print("N/A,");
754 pw.print(nativeAllocated + dalvikAllocated); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700755
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800756 // Heap info - free
757 pw.print(nativeFree); pw.print(',');
758 pw.print(dalvikFree); pw.print(',');
759 pw.print("N/A,");
760 pw.print(nativeFree + dalvikFree); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700761
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800762 // Heap info - proportional set size
763 pw.print(memInfo.nativePss); pw.print(',');
764 pw.print(memInfo.dalvikPss); pw.print(',');
765 pw.print(memInfo.otherPss); pw.print(',');
766 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700767
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800768 // Heap info - shared
Bob Leee5408332009-09-04 18:31:17 -0700769 pw.print(nativeShared); pw.print(',');
770 pw.print(dalvikShared); pw.print(',');
771 pw.print(otherShared); pw.print(',');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800772 pw.print(nativeShared + dalvikShared + otherShared); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800774 // Heap info - private
Bob Leee5408332009-09-04 18:31:17 -0700775 pw.print(nativePrivate); pw.print(',');
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800776 pw.print(dalvikPrivate); pw.print(',');
777 pw.print(otherPrivate); pw.print(',');
778 pw.print(nativePrivate + dalvikPrivate + otherPrivate); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800780 // Object counts
781 pw.print(viewInstanceCount); pw.print(',');
782 pw.print(viewRootInstanceCount); pw.print(',');
783 pw.print(appContextInstanceCount); pw.print(',');
784 pw.print(activityInstanceCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700785
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800786 pw.print(globalAssetCount); pw.print(',');
787 pw.print(globalAssetManagerCount); pw.print(',');
788 pw.print(binderLocalObjectCount); pw.print(',');
789 pw.print(binderProxyObjectCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800791 pw.print(binderDeathObjectCount); pw.print(',');
792 pw.print(openSslSocketCount); pw.print(',');
Bob Leee5408332009-09-04 18:31:17 -0700793
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800794 // SQL
795 pw.print(sqliteAllocated); pw.print(',');
Vasu Noric3849202010-03-09 10:47:25 -0800796 pw.print(stats.memoryUsed / 1024); pw.print(',');
797 pw.print(stats.pageCacheOverflo / 1024); pw.print(',');
798 pw.print(stats.largestMemAlloc / 1024); pw.print(',');
799 for (int i = 0; i < stats.dbStats.size(); i++) {
800 DbStats dbStats = stats.dbStats.get(i);
801 printRow(pw, DB_INFO_FORMAT, dbStats.pageSize, dbStats.dbSize,
Vasu Nori90a367262010-04-12 12:49:09 -0700802 dbStats.lookaside, dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -0800803 pw.print(',');
804 }
Bob Leee5408332009-09-04 18:31:17 -0700805
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800806 return;
807 }
Bob Leee5408332009-09-04 18:31:17 -0700808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800809 // otherwise, show human-readable format
810 printRow(pw, HEAP_COLUMN, "", "native", "dalvik", "other", "total");
811 printRow(pw, HEAP_COLUMN, "size:", nativeMax, dalvikMax, "N/A", nativeMax + dalvikMax);
812 printRow(pw, HEAP_COLUMN, "allocated:", nativeAllocated, dalvikAllocated, "N/A",
813 nativeAllocated + dalvikAllocated);
814 printRow(pw, HEAP_COLUMN, "free:", nativeFree, dalvikFree, "N/A",
815 nativeFree + dalvikFree);
816
817 printRow(pw, HEAP_COLUMN, "(Pss):", memInfo.nativePss, memInfo.dalvikPss,
818 memInfo.otherPss, memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss);
819
820 printRow(pw, HEAP_COLUMN, "(shared dirty):", nativeShared, dalvikShared, otherShared,
821 nativeShared + dalvikShared + otherShared);
822 printRow(pw, HEAP_COLUMN, "(priv dirty):", nativePrivate, dalvikPrivate, otherPrivate,
823 nativePrivate + dalvikPrivate + otherPrivate);
824
825 pw.println(" ");
826 pw.println(" Objects");
827 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRoots:",
828 viewRootInstanceCount);
829
830 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
831 "Activities:", activityInstanceCount);
832
833 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount,
834 "AssetManagers:", globalAssetManagerCount);
835
836 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount,
837 "Proxy Binders:", binderProxyObjectCount);
838 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount);
839
840 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount);
Bob Leee5408332009-09-04 18:31:17 -0700841
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 // SQLite mem info
843 pw.println(" ");
844 pw.println(" SQL");
Vasu Nori3c7131f2010-09-21 14:36:57 -0700845 printRow(pw, TWO_COUNT_COLUMNS_DB, "heap:", sqliteAllocated, "MEMORY_USED:",
Vasu Noric3849202010-03-09 10:47:25 -0800846 stats.memoryUsed / 1024);
Vasu Nori3c7131f2010-09-21 14:36:57 -0700847 printRow(pw, TWO_COUNT_COLUMNS_DB, "PAGECACHE_OVERFLOW:",
848 stats.pageCacheOverflo / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024);
Vasu Noric3849202010-03-09 10:47:25 -0800849 pw.println(" ");
850 int N = stats.dbStats.size();
851 if (N > 0) {
852 pw.println(" DATABASES");
Vasu Nori3c7131f2010-09-21 14:36:57 -0700853 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache",
854 "Dbname");
Vasu Noric3849202010-03-09 10:47:25 -0800855 for (int i = 0; i < N; i++) {
856 DbStats dbStats = stats.dbStats.get(i);
Vasu Nori3c7131f2010-09-21 14:36:57 -0700857 printRow(pw, DB_INFO_FORMAT,
858 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ",
859 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ",
860 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ",
861 dbStats.cache, dbStats.dbName);
Vasu Noric3849202010-03-09 10:47:25 -0800862 }
863 }
Bob Leee5408332009-09-04 18:31:17 -0700864
Dianne Hackborn82e1ee92009-08-11 18:56:41 -0700865 // Asset details.
866 String assetAlloc = AssetManager.getAssetAllocations();
867 if (assetAlloc != null) {
868 pw.println(" ");
869 pw.println(" Asset Allocations");
870 pw.print(assetAlloc);
871 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800872 }
873
874 private void printRow(PrintWriter pw, String format, Object...objs) {
875 pw.println(String.format(format, objs));
876 }
877 }
878
879 private final class H extends Handler {
880 public static final int LAUNCH_ACTIVITY = 100;
881 public static final int PAUSE_ACTIVITY = 101;
882 public static final int PAUSE_ACTIVITY_FINISHING= 102;
883 public static final int STOP_ACTIVITY_SHOW = 103;
884 public static final int STOP_ACTIVITY_HIDE = 104;
885 public static final int SHOW_WINDOW = 105;
886 public static final int HIDE_WINDOW = 106;
887 public static final int RESUME_ACTIVITY = 107;
888 public static final int SEND_RESULT = 108;
889 public static final int DESTROY_ACTIVITY = 109;
890 public static final int BIND_APPLICATION = 110;
891 public static final int EXIT_APPLICATION = 111;
892 public static final int NEW_INTENT = 112;
893 public static final int RECEIVER = 113;
894 public static final int CREATE_SERVICE = 114;
895 public static final int SERVICE_ARGS = 115;
896 public static final int STOP_SERVICE = 116;
897 public static final int REQUEST_THUMBNAIL = 117;
898 public static final int CONFIGURATION_CHANGED = 118;
899 public static final int CLEAN_UP_CONTEXT = 119;
900 public static final int GC_WHEN_IDLE = 120;
901 public static final int BIND_SERVICE = 121;
902 public static final int UNBIND_SERVICE = 122;
903 public static final int DUMP_SERVICE = 123;
904 public static final int LOW_MEMORY = 124;
905 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125;
906 public static final int RELAUNCH_ACTIVITY = 126;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800907 public static final int PROFILER_CONTROL = 127;
Christopher Tate181fafa2009-05-14 11:12:14 -0700908 public static final int CREATE_BACKUP_AGENT = 128;
Christopher Tate5e1ab332009-09-01 20:32:49 -0700909 public static final int DESTROY_BACKUP_AGENT = 129;
910 public static final int SUICIDE = 130;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700911 public static final int REMOVE_PROVIDER = 131;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -0800912 public static final int ENABLE_JIT = 132;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700913 public static final int DISPATCH_PACKAGE_BROADCAST = 133;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700914 public static final int SCHEDULE_CRASH = 134;
Andy McFadden824c5102010-07-09 16:26:57 -0700915 public static final int DUMP_HEAP = 135;
Dianne Hackborn625ac272010-09-17 18:29:22 -0700916 public static final int DUMP_ACTIVITY = 136;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 String codeToString(int code) {
Dianne Hackborn287952c2010-09-22 22:34:31 -0700918 if (DEBUG_MESSAGES) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 switch (code) {
920 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";
921 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";
922 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING";
923 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW";
924 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE";
925 case SHOW_WINDOW: return "SHOW_WINDOW";
926 case HIDE_WINDOW: return "HIDE_WINDOW";
927 case RESUME_ACTIVITY: return "RESUME_ACTIVITY";
928 case SEND_RESULT: return "SEND_RESULT";
929 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY";
930 case BIND_APPLICATION: return "BIND_APPLICATION";
931 case EXIT_APPLICATION: return "EXIT_APPLICATION";
932 case NEW_INTENT: return "NEW_INTENT";
933 case RECEIVER: return "RECEIVER";
934 case CREATE_SERVICE: return "CREATE_SERVICE";
935 case SERVICE_ARGS: return "SERVICE_ARGS";
936 case STOP_SERVICE: return "STOP_SERVICE";
937 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL";
938 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED";
939 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT";
940 case GC_WHEN_IDLE: return "GC_WHEN_IDLE";
941 case BIND_SERVICE: return "BIND_SERVICE";
942 case UNBIND_SERVICE: return "UNBIND_SERVICE";
943 case DUMP_SERVICE: return "DUMP_SERVICE";
944 case LOW_MEMORY: return "LOW_MEMORY";
945 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED";
946 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY";
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -0800947 case PROFILER_CONTROL: return "PROFILER_CONTROL";
Christopher Tate181fafa2009-05-14 11:12:14 -0700948 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT";
949 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
Christopher Tate5e1ab332009-09-01 20:32:49 -0700950 case SUICIDE: return "SUICIDE";
Dianne Hackborn9bfb7072009-09-22 11:37:40 -0700951 case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
Dianne Hackborn2a9094d2010-02-03 19:20:09 -0800952 case ENABLE_JIT: return "ENABLE_JIT";
Dianne Hackborn4416c3d2010-05-04 17:22:49 -0700953 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -0700954 case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
Andy McFadden824c5102010-07-09 16:26:57 -0700955 case DUMP_HEAP: return "DUMP_HEAP";
Dianne Hackborn625ac272010-09-17 18:29:22 -0700956 case DUMP_ACTIVITY: return "DUMP_ACTIVITY";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 }
958 }
959 return "(unknown)";
960 }
961 public void handleMessage(Message msg) {
Dianne Hackborn287952c2010-09-22 22:34:31 -0700962 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 switch (msg.what) {
964 case LAUNCH_ACTIVITY: {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700965 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966
967 r.packageInfo = getPackageInfoNoCheck(
968 r.activityInfo.applicationInfo);
Christopher Tateb70f3df2009-04-07 16:07:59 -0700969 handleLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800970 } break;
971 case RELAUNCH_ACTIVITY: {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -0700972 ActivityClientRecord r = (ActivityClientRecord)msg.obj;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800973 handleRelaunchActivity(r, msg.arg1);
974 } break;
975 case PAUSE_ACTIVITY:
976 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
Bob Leee5408332009-09-04 18:31:17 -0700977 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 break;
979 case PAUSE_ACTIVITY_FINISHING:
980 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2);
981 break;
982 case STOP_ACTIVITY_SHOW:
983 handleStopActivity((IBinder)msg.obj, true, msg.arg2);
984 break;
985 case STOP_ACTIVITY_HIDE:
986 handleStopActivity((IBinder)msg.obj, false, msg.arg2);
987 break;
988 case SHOW_WINDOW:
989 handleWindowVisibility((IBinder)msg.obj, true);
990 break;
991 case HIDE_WINDOW:
992 handleWindowVisibility((IBinder)msg.obj, false);
993 break;
994 case RESUME_ACTIVITY:
995 handleResumeActivity((IBinder)msg.obj, true,
996 msg.arg1 != 0);
997 break;
998 case SEND_RESULT:
999 handleSendResult((ResultData)msg.obj);
1000 break;
1001 case DESTROY_ACTIVITY:
1002 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0,
1003 msg.arg2, false);
1004 break;
1005 case BIND_APPLICATION:
1006 AppBindData data = (AppBindData)msg.obj;
1007 handleBindApplication(data);
1008 break;
1009 case EXIT_APPLICATION:
1010 if (mInitialApplication != null) {
1011 mInitialApplication.onTerminate();
1012 }
1013 Looper.myLooper().quit();
1014 break;
1015 case NEW_INTENT:
1016 handleNewIntent((NewIntentData)msg.obj);
1017 break;
1018 case RECEIVER:
1019 handleReceiver((ReceiverData)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001020 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 break;
1022 case CREATE_SERVICE:
1023 handleCreateService((CreateServiceData)msg.obj);
1024 break;
1025 case BIND_SERVICE:
1026 handleBindService((BindServiceData)msg.obj);
1027 break;
1028 case UNBIND_SERVICE:
1029 handleUnbindService((BindServiceData)msg.obj);
1030 break;
1031 case SERVICE_ARGS:
1032 handleServiceArgs((ServiceArgsData)msg.obj);
1033 break;
1034 case STOP_SERVICE:
1035 handleStopService((IBinder)msg.obj);
Bob Leee5408332009-09-04 18:31:17 -07001036 maybeSnapshot();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 break;
1038 case REQUEST_THUMBNAIL:
1039 handleRequestThumbnail((IBinder)msg.obj);
1040 break;
1041 case CONFIGURATION_CHANGED:
1042 handleConfigurationChanged((Configuration)msg.obj);
1043 break;
1044 case CLEAN_UP_CONTEXT:
1045 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj;
1046 cci.context.performFinalCleanup(cci.who, cci.what);
1047 break;
1048 case GC_WHEN_IDLE:
1049 scheduleGcIdler();
1050 break;
1051 case DUMP_SERVICE:
Dianne Hackborn625ac272010-09-17 18:29:22 -07001052 handleDumpService((DumpComponentInfo)msg.obj);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 break;
1054 case LOW_MEMORY:
1055 handleLowMemory();
1056 break;
1057 case ACTIVITY_CONFIGURATION_CHANGED:
1058 handleActivityConfigurationChanged((IBinder)msg.obj);
1059 break;
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001060 case PROFILER_CONTROL:
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07001061 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08001062 break;
Christopher Tate181fafa2009-05-14 11:12:14 -07001063 case CREATE_BACKUP_AGENT:
1064 handleCreateBackupAgent((CreateBackupAgentData)msg.obj);
1065 break;
1066 case DESTROY_BACKUP_AGENT:
1067 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj);
1068 break;
Christopher Tate5e1ab332009-09-01 20:32:49 -07001069 case SUICIDE:
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07001070 Process.killProcess(Process.myPid());
1071 break;
1072 case REMOVE_PROVIDER:
1073 completeRemoveProvider((IContentProvider)msg.obj);
Christopher Tate5e1ab332009-09-01 20:32:49 -07001074 break;
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001075 case ENABLE_JIT:
1076 ensureJitEnabled();
1077 break;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001078 case DISPATCH_PACKAGE_BROADCAST:
1079 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
1080 break;
Dianne Hackborn9d39d0c2010-06-24 15:57:42 -07001081 case SCHEDULE_CRASH:
1082 throw new RemoteServiceException((String)msg.obj);
Andy McFadden824c5102010-07-09 16:26:57 -07001083 case DUMP_HEAP:
1084 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj);
1085 break;
Dianne Hackborn625ac272010-09-17 18:29:22 -07001086 case DUMP_ACTIVITY:
1087 handleDumpActivity((DumpComponentInfo)msg.obj);
1088 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001089 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07001090 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 }
Bob Leee5408332009-09-04 18:31:17 -07001092
1093 void maybeSnapshot() {
1094 if (mBoundApplication != null) {
Sen Hubde75702010-05-28 01:54:03 -07001095 // convert the *private* ActivityThread.PackageInfo to *public* known
1096 // android.content.pm.PackageInfo
1097 String packageName = mBoundApplication.info.mPackageName;
1098 android.content.pm.PackageInfo packageInfo = null;
1099 try {
1100 Context context = getSystemContext();
1101 if(context == null) {
1102 Log.e(TAG, "cannot get a valid context");
1103 return;
1104 }
1105 PackageManager pm = context.getPackageManager();
1106 if(pm == null) {
1107 Log.e(TAG, "cannot get a valid PackageManager");
1108 return;
1109 }
1110 packageInfo = pm.getPackageInfo(
1111 packageName, PackageManager.GET_ACTIVITIES);
1112 } catch (NameNotFoundException e) {
1113 Log.e(TAG, "cannot get package info for " + packageName, e);
1114 }
1115 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo);
Bob Leee5408332009-09-04 18:31:17 -07001116 }
1117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 }
1119
1120 private final class Idler implements MessageQueue.IdleHandler {
1121 public final boolean queueIdle() {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001122 ActivityClientRecord a = mNewActivities;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001123 if (a != null) {
1124 mNewActivities = null;
1125 IActivityManager am = ActivityManagerNative.getDefault();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001126 ActivityClientRecord prev;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001127 do {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001128 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 TAG, "Reporting idle of " + a +
1130 " finished=" +
1131 (a.activity != null ? a.activity.mFinished : false));
1132 if (a.activity != null && !a.activity.mFinished) {
1133 try {
Dianne Hackborne88846e2009-09-30 21:34:25 -07001134 am.activityIdle(a.token, a.createdConfig);
1135 a.createdConfig = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 } catch (RemoteException ex) {
1137 }
1138 }
1139 prev = a;
1140 a = a.nextIdle;
1141 prev.nextIdle = null;
1142 } while (a != null);
1143 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001144 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001145 return false;
1146 }
1147 }
1148
1149 final class GcIdler implements MessageQueue.IdleHandler {
1150 public final boolean queueIdle() {
1151 doGcIfNeeded();
1152 return false;
1153 }
1154 }
1155
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001156 private final static class ResourcesKey {
1157 final private String mResDir;
1158 final private float mScale;
1159 final private int mHash;
Bob Leee5408332009-09-04 18:31:17 -07001160
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001161 ResourcesKey(String resDir, float scale) {
1162 mResDir = resDir;
1163 mScale = scale;
1164 mHash = mResDir.hashCode() << 2 + (int) (mScale * 2);
1165 }
Bob Leee5408332009-09-04 18:31:17 -07001166
Mitsuru Oshimaba3ba572009-07-08 18:49:26 -07001167 @Override
1168 public int hashCode() {
1169 return mHash;
1170 }
1171
1172 @Override
1173 public boolean equals(Object obj) {
1174 if (!(obj instanceof ResourcesKey)) {
1175 return false;
1176 }
1177 ResourcesKey peer = (ResourcesKey) obj;
1178 return mResDir.equals(peer.mResDir) && mScale == peer.mScale;
1179 }
1180 }
1181
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001182 public static final ActivityThread currentActivityThread() {
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07001183 return sThreadLocal.get();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001186 public static final String currentPackageName() {
1187 ActivityThread am = currentActivityThread();
1188 return (am != null && am.mBoundApplication != null)
1189 ? am.mBoundApplication.processName : null;
1190 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001191
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001192 public static final Application currentApplication() {
1193 ActivityThread am = currentActivityThread();
1194 return am != null ? am.mInitialApplication : null;
1195 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001197 public static IPackageManager getPackageManager() {
1198 if (sPackageManager != null) {
1199 //Slog.v("PackageManager", "returning cur default = " + sPackageManager);
1200 return sPackageManager;
1201 }
1202 IBinder b = ServiceManager.getService("package");
1203 //Slog.v("PackageManager", "default service binder = " + b);
1204 sPackageManager = IPackageManager.Stub.asInterface(b);
1205 //Slog.v("PackageManager", "default service = " + sPackageManager);
1206 return sPackageManager;
1207 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001208
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001209 DisplayMetrics getDisplayMetricsLocked(boolean forceUpdate) {
1210 if (mDisplayMetrics != null && !forceUpdate) {
1211 return mDisplayMetrics;
1212 }
1213 if (mDisplay == null) {
1214 WindowManager wm = WindowManagerImpl.getDefault();
1215 mDisplay = wm.getDefaultDisplay();
1216 }
1217 DisplayMetrics metrics = mDisplayMetrics = new DisplayMetrics();
1218 mDisplay.getMetrics(metrics);
1219 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h="
1220 // + metrics.heightPixels + " den=" + metrics.density
1221 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi);
1222 return metrics;
1223 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001225 /**
1226 * Creates the top level Resources for applications with the given compatibility info.
1227 *
1228 * @param resDir the resource directory.
1229 * @param compInfo the compability info. It will use the default compatibility info when it's
1230 * null.
1231 */
1232 Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
1233 ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
1234 Resources r;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001236 // Resources is app scale dependent.
1237 if (false) {
1238 Slog.w(TAG, "getTopLevelResources: " + resDir + " / "
1239 + compInfo.applicationScale);
1240 }
1241 WeakReference<Resources> wr = mActiveResources.get(key);
1242 r = wr != null ? wr.get() : null;
1243 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
1244 if (r != null && r.getAssets().isUpToDate()) {
1245 if (false) {
1246 Slog.w(TAG, "Returning cached resources " + r + " " + resDir
1247 + ": appScale=" + r.getCompatibilityInfo().applicationScale);
1248 }
1249 return r;
1250 }
1251 }
1252
1253 //if (r != null) {
1254 // Slog.w(TAG, "Throwing away out-of-date resources!!!! "
1255 // + r + " " + resDir);
1256 //}
1257
1258 AssetManager assets = new AssetManager();
1259 if (assets.addAssetPath(resDir) == 0) {
1260 return null;
1261 }
1262
1263 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
1264 DisplayMetrics metrics = getDisplayMetricsLocked(false);
1265 r = new Resources(assets, metrics, getConfiguration(), compInfo);
1266 if (false) {
1267 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": "
1268 + r.getConfiguration() + " appScale="
1269 + r.getCompatibilityInfo().applicationScale);
1270 }
1271
1272 synchronized (mPackages) {
1273 WeakReference<Resources> wr = mActiveResources.get(key);
1274 Resources existing = wr != null ? wr.get() : null;
1275 if (existing != null && existing.getAssets().isUpToDate()) {
1276 // Someone else already created the resources while we were
1277 // unlocked; go ahead and use theirs.
1278 r.getAssets().close();
1279 return existing;
1280 }
1281
1282 // XXX need to remove entries when weak references go away
1283 mActiveResources.put(key, new WeakReference<Resources>(r));
1284 return r;
1285 }
1286 }
1287
1288 /**
1289 * Creates the top level resources for the given package.
1290 */
1291 Resources getTopLevelResources(String resDir, LoadedApk pkgInfo) {
1292 return getTopLevelResources(resDir, pkgInfo.mCompatibilityInfo);
1293 }
1294
1295 final Handler getHandler() {
1296 return mH;
1297 }
1298
1299 public final LoadedApk getPackageInfo(String packageName, int flags) {
1300 synchronized (mPackages) {
1301 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001302 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) {
1303 ref = mPackages.get(packageName);
1304 } else {
1305 ref = mResourcePackages.get(packageName);
1306 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001307 LoadedApk packageInfo = ref != null ? ref.get() : null;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001308 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo);
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07001309 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir
1310 // + ": " + packageInfo.mResources.getAssets().isUpToDate());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 if (packageInfo != null && (packageInfo.mResources == null
1312 || packageInfo.mResources.getAssets().isUpToDate())) {
1313 if (packageInfo.isSecurityViolation()
1314 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) {
1315 throw new SecurityException(
1316 "Requesting code from " + packageName
1317 + " to be run in process "
1318 + mBoundApplication.processName
1319 + "/" + mBoundApplication.appInfo.uid);
1320 }
1321 return packageInfo;
1322 }
1323 }
1324
1325 ApplicationInfo ai = null;
1326 try {
1327 ai = getPackageManager().getApplicationInfo(packageName,
1328 PackageManager.GET_SHARED_LIBRARY_FILES);
1329 } catch (RemoteException e) {
1330 }
1331
1332 if (ai != null) {
1333 return getPackageInfo(ai, flags);
1334 }
1335
1336 return null;
1337 }
1338
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001339 public final LoadedApk getPackageInfo(ApplicationInfo ai, int flags) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0;
1341 boolean securityViolation = includeCode && ai.uid != 0
1342 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null
1343 ? ai.uid != mBoundApplication.appInfo.uid : true);
1344 if ((flags&(Context.CONTEXT_INCLUDE_CODE
1345 |Context.CONTEXT_IGNORE_SECURITY))
1346 == Context.CONTEXT_INCLUDE_CODE) {
1347 if (securityViolation) {
1348 String msg = "Requesting code from " + ai.packageName
1349 + " (with uid " + ai.uid + ")";
1350 if (mBoundApplication != null) {
1351 msg = msg + " to be run in process "
1352 + mBoundApplication.processName + " (with uid "
1353 + mBoundApplication.appInfo.uid + ")";
1354 }
1355 throw new SecurityException(msg);
1356 }
1357 }
1358 return getPackageInfo(ai, null, securityViolation, includeCode);
1359 }
1360
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001361 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 return getPackageInfo(ai, null, false, true);
1363 }
1364
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001365 private final LoadedApk getPackageInfo(ApplicationInfo aInfo,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001366 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
1367 synchronized (mPackages) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001368 WeakReference<LoadedApk> ref;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 if (includeCode) {
1370 ref = mPackages.get(aInfo.packageName);
1371 } else {
1372 ref = mResourcePackages.get(aInfo.packageName);
1373 }
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001374 LoadedApk packageInfo = ref != null ? ref.get() : null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 if (packageInfo == null || (packageInfo.mResources != null
1376 && !packageInfo.mResources.getAssets().isUpToDate())) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001377 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001378 : "Loading resource-only package ") + aInfo.packageName
1379 + " (in " + (mBoundApplication != null
1380 ? mBoundApplication.processName : null)
1381 + ")");
1382 packageInfo =
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001383 new LoadedApk(this, aInfo, this, baseLoader,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001384 securityViolation, includeCode &&
1385 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0);
1386 if (includeCode) {
1387 mPackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001388 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001389 } else {
1390 mResourcePackages.put(aInfo.packageName,
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001391 new WeakReference<LoadedApk>(packageInfo));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001392 }
1393 }
1394 return packageInfo;
1395 }
1396 }
1397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 ActivityThread() {
1399 }
1400
1401 public ApplicationThread getApplicationThread()
1402 {
1403 return mAppThread;
1404 }
1405
1406 public Instrumentation getInstrumentation()
1407 {
1408 return mInstrumentation;
1409 }
1410
1411 public Configuration getConfiguration() {
1412 return mConfiguration;
1413 }
1414
1415 public boolean isProfiling() {
1416 return mBoundApplication != null && mBoundApplication.profileFile != null;
1417 }
1418
1419 public String getProfileFilePath() {
1420 return mBoundApplication.profileFile;
1421 }
1422
1423 public Looper getLooper() {
1424 return mLooper;
1425 }
1426
1427 public Application getApplication() {
1428 return mInitialApplication;
1429 }
Bob Leee5408332009-09-04 18:31:17 -07001430
Dianne Hackbornd97c7ad2009-06-19 11:37:35 -07001431 public String getProcessName() {
1432 return mBoundApplication.processName;
1433 }
Bob Leee5408332009-09-04 18:31:17 -07001434
Dianne Hackborn21556372010-02-04 16:34:40 -08001435 public ContextImpl getSystemContext() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001436 synchronized (this) {
1437 if (mSystemContext == null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001438 ContextImpl context =
1439 ContextImpl.createSystemContext(this);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001440 LoadedApk info = new LoadedApk(this, "android", context, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 context.init(info, null, this);
1442 context.getResources().updateConfiguration(
1443 getConfiguration(), getDisplayMetricsLocked(false));
1444 mSystemContext = context;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001445 //Slog.i(TAG, "Created system resources " + context.getResources()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001446 // + ": " + context.getResources().getConfiguration());
1447 }
1448 }
1449 return mSystemContext;
1450 }
1451
Mike Cleron432b7132009-09-24 15:28:29 -07001452 public void installSystemApplicationInfo(ApplicationInfo info) {
1453 synchronized (this) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001454 ContextImpl context = getSystemContext();
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001455 context.init(new LoadedApk(this, "android", context, info), null, this);
Mike Cleron432b7132009-09-24 15:28:29 -07001456 }
1457 }
1458
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08001459 void ensureJitEnabled() {
1460 if (!mJitEnabled) {
1461 mJitEnabled = true;
1462 dalvik.system.VMRuntime.getRuntime().startJitCompilation();
1463 }
1464 }
1465
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001466 void scheduleGcIdler() {
1467 if (!mGcIdlerScheduled) {
1468 mGcIdlerScheduled = true;
1469 Looper.myQueue().addIdleHandler(mGcIdler);
1470 }
1471 mH.removeMessages(H.GC_WHEN_IDLE);
1472 }
1473
1474 void unscheduleGcIdler() {
1475 if (mGcIdlerScheduled) {
1476 mGcIdlerScheduled = false;
1477 Looper.myQueue().removeIdleHandler(mGcIdler);
1478 }
1479 mH.removeMessages(H.GC_WHEN_IDLE);
1480 }
1481
1482 void doGcIfNeeded() {
1483 mGcIdlerScheduled = false;
1484 final long now = SystemClock.uptimeMillis();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001485 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 // + "m now=" + now);
1487 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001488 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001489 BinderInternal.forceGc("bg");
1490 }
1491 }
1492
1493 public final ActivityInfo resolveActivityInfo(Intent intent) {
1494 ActivityInfo aInfo = intent.resolveActivityInfo(
1495 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES);
1496 if (aInfo == null) {
1497 // Throw an exception.
1498 Instrumentation.checkStartActivityResult(
1499 IActivityManager.START_CLASS_NOT_FOUND, intent);
1500 }
1501 return aInfo;
1502 }
Bob Leee5408332009-09-04 18:31:17 -07001503
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 public final Activity startActivityNow(Activity parent, String id,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001505 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001506 Activity.NonConfigurationInstances lastNonConfigurationInstances) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001507 ActivityClientRecord r = new ActivityClientRecord();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508 r.token = token;
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001509 r.ident = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 r.intent = intent;
1511 r.state = state;
1512 r.parent = parent;
1513 r.embeddedID = id;
1514 r.activityInfo = activityInfo;
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001515 r.lastNonConfigurationInstances = lastNonConfigurationInstances;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001516 if (localLOGV) {
1517 ComponentName compname = intent.getComponent();
1518 String name;
1519 if (compname != null) {
1520 name = compname.toShortString();
1521 } else {
1522 name = "(Intent " + intent + ").getComponent() returned null";
1523 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001524 Slog.v(TAG, "Performing launch: action=" + intent.getAction()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 + ", comp=" + name
1526 + ", token=" + token);
1527 }
Christopher Tateb70f3df2009-04-07 16:07:59 -07001528 return performLaunchActivity(r, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001529 }
1530
1531 public final Activity getActivity(IBinder token) {
1532 return mActivities.get(token).activity;
1533 }
1534
1535 public final void sendActivityResult(
1536 IBinder token, String id, int requestCode,
1537 int resultCode, Intent data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001538 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id
Chris Tate8a7dc172009-03-24 20:11:42 -07001539 + " req=" + requestCode + " res=" + resultCode + " data=" + data);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>();
1541 list.add(new ResultInfo(id, requestCode, resultCode, data));
1542 mAppThread.scheduleSendResult(token, list);
1543 }
1544
1545 // if the thread hasn't started yet, we don't have the handler, so just
1546 // save the messages until we're ready.
1547 private final void queueOrSendMessage(int what, Object obj) {
1548 queueOrSendMessage(what, obj, 0, 0);
1549 }
1550
1551 private final void queueOrSendMessage(int what, Object obj, int arg1) {
1552 queueOrSendMessage(what, obj, arg1, 0);
1553 }
1554
1555 private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
1556 synchronized (this) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07001557 if (DEBUG_MESSAGES) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
1559 + ": " + arg1 + " / " + obj);
1560 Message msg = Message.obtain();
1561 msg.what = what;
1562 msg.obj = obj;
1563 msg.arg1 = arg1;
1564 msg.arg2 = arg2;
1565 mH.sendMessage(msg);
1566 }
1567 }
1568
Dianne Hackborn21556372010-02-04 16:34:40 -08001569 final void scheduleContextCleanup(ContextImpl context, String who,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 String what) {
1571 ContextCleanupInfo cci = new ContextCleanupInfo();
1572 cci.context = context;
1573 cci.who = who;
1574 cci.what = what;
1575 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
1576 }
1577
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001578 private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001579 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
1580
1581 ActivityInfo aInfo = r.activityInfo;
1582 if (r.packageInfo == null) {
1583 r.packageInfo = getPackageInfo(aInfo.applicationInfo,
1584 Context.CONTEXT_INCLUDE_CODE);
1585 }
Bob Leee5408332009-09-04 18:31:17 -07001586
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001587 ComponentName component = r.intent.getComponent();
1588 if (component == null) {
1589 component = r.intent.resolveActivity(
1590 mInitialApplication.getPackageManager());
1591 r.intent.setComponent(component);
1592 }
1593
1594 if (r.activityInfo.targetActivity != null) {
1595 component = new ComponentName(r.activityInfo.packageName,
1596 r.activityInfo.targetActivity);
1597 }
1598
1599 Activity activity = null;
1600 try {
1601 java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
1602 activity = mInstrumentation.newActivity(
1603 cl, component.getClassName(), r.intent);
1604 r.intent.setExtrasClassLoader(cl);
1605 if (r.state != null) {
1606 r.state.setClassLoader(cl);
1607 }
1608 } catch (Exception e) {
1609 if (!mInstrumentation.onException(activity, e)) {
1610 throw new RuntimeException(
1611 "Unable to instantiate activity " + component
1612 + ": " + e.toString(), e);
1613 }
1614 }
1615
1616 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08001617 Application app = r.packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07001618
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001619 if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
1620 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 TAG, r + ": app=" + app
1622 + ", appName=" + app.getPackageName()
1623 + ", pkg=" + r.packageInfo.getPackageName()
1624 + ", comp=" + r.intent.getComponent().toShortString()
1625 + ", dir=" + r.packageInfo.getAppDir());
1626
1627 if (activity != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08001628 ContextImpl appContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001629 appContext.init(r.packageInfo, r.token, this);
1630 appContext.setOuterContext(activity);
1631 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());
1632 Configuration config = new Configuration(mConfiguration);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001633 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07001634 + r.activityInfo.name + " with config " + config);
Dianne Hackbornb06ea702009-07-13 13:07:51 -07001635 activity.attach(appContext, this, getInstrumentation(), r.token,
1636 r.ident, app, r.intent, r.activityInfo, title, r.parent,
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001637 r.embeddedID, r.lastNonConfigurationInstances, config);
Bob Leee5408332009-09-04 18:31:17 -07001638
Christopher Tateb70f3df2009-04-07 16:07:59 -07001639 if (customIntent != null) {
1640 activity.mIntent = customIntent;
1641 }
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07001642 r.lastNonConfigurationInstances = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001643 activity.mStartedActivity = false;
1644 int theme = r.activityInfo.getThemeResource();
1645 if (theme != 0) {
1646 activity.setTheme(theme);
1647 }
1648
1649 activity.mCalled = false;
1650 mInstrumentation.callActivityOnCreate(activity, r.state);
1651 if (!activity.mCalled) {
1652 throw new SuperNotCalledException(
1653 "Activity " + r.intent.getComponent().toShortString() +
1654 " did not call through to super.onCreate()");
1655 }
1656 r.activity = activity;
1657 r.stopped = true;
1658 if (!r.activity.mFinished) {
1659 activity.performStart();
1660 r.stopped = false;
1661 }
1662 if (!r.activity.mFinished) {
1663 if (r.state != null) {
1664 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
1665 }
1666 }
1667 if (!r.activity.mFinished) {
1668 activity.mCalled = false;
1669 mInstrumentation.callActivityOnPostCreate(activity, r.state);
1670 if (!activity.mCalled) {
1671 throw new SuperNotCalledException(
1672 "Activity " + r.intent.getComponent().toShortString() +
1673 " did not call through to super.onPostCreate()");
1674 }
1675 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001676 }
1677 r.paused = true;
1678
1679 mActivities.put(r.token, r);
1680
1681 } catch (SuperNotCalledException e) {
1682 throw e;
1683
1684 } catch (Exception e) {
1685 if (!mInstrumentation.onException(activity, e)) {
1686 throw new RuntimeException(
1687 "Unable to start activity " + component
1688 + ": " + e.toString(), e);
1689 }
1690 }
1691
1692 return activity;
1693 }
1694
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001695 private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001696 // If we are getting ready to gc after going to the background, well
1697 // we are back active so skip it.
1698 unscheduleGcIdler();
1699
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001700 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001701 TAG, "Handling launch of " + r);
Christopher Tateb70f3df2009-04-07 16:07:59 -07001702 Activity a = performLaunchActivity(r, customIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001703
1704 if (a != null) {
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08001705 r.createdConfig = new Configuration(mConfiguration);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001706 Bundle oldState = r.state;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001707 handleResumeActivity(r.token, false, r.isForward);
1708
1709 if (!r.activity.mFinished && r.startsNotResumed) {
1710 // The activity manager actually wants this one to start out
1711 // paused, because it needs to be visible but isn't in the
1712 // foreground. We accomplish this by going through the
1713 // normal startup (because activities expect to go through
1714 // onResume() the first time they run, before their window
1715 // is displayed), and then pausing it. However, in this case
1716 // we do -not- need to do the full pause cycle (of freezing
1717 // and such) because the activity manager assumes it can just
1718 // retain the current state it has.
1719 try {
1720 r.activity.mCalled = false;
1721 mInstrumentation.callActivityOnPause(r.activity);
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -08001722 // We need to keep around the original state, in case
1723 // we need to be created again.
1724 r.state = oldState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001725 if (!r.activity.mCalled) {
1726 throw new SuperNotCalledException(
1727 "Activity " + r.intent.getComponent().toShortString() +
1728 " did not call through to super.onPause()");
1729 }
1730
1731 } catch (SuperNotCalledException e) {
1732 throw e;
1733
1734 } catch (Exception e) {
1735 if (!mInstrumentation.onException(r.activity, e)) {
1736 throw new RuntimeException(
1737 "Unable to pause activity "
1738 + r.intent.getComponent().toShortString()
1739 + ": " + e.toString(), e);
1740 }
1741 }
1742 r.paused = true;
1743 }
1744 } else {
1745 // If there was an error, for any reason, tell the activity
1746 // manager to stop us.
1747 try {
1748 ActivityManagerNative.getDefault()
1749 .finishActivity(r.token, Activity.RESULT_CANCELED, null);
1750 } catch (RemoteException ex) {
1751 }
1752 }
1753 }
1754
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001755 private final void deliverNewIntents(ActivityClientRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001756 List<Intent> intents) {
1757 final int N = intents.size();
1758 for (int i=0; i<N; i++) {
1759 Intent intent = intents.get(i);
1760 intent.setExtrasClassLoader(r.activity.getClassLoader());
1761 mInstrumentation.callActivityOnNewIntent(r.activity, intent);
1762 }
1763 }
1764
1765 public final void performNewIntents(IBinder token,
1766 List<Intent> intents) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001767 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001768 if (r != null) {
1769 final boolean resumed = !r.paused;
1770 if (resumed) {
1771 mInstrumentation.callActivityOnPause(r.activity);
1772 }
1773 deliverNewIntents(r, intents);
1774 if (resumed) {
1775 mInstrumentation.callActivityOnResume(r.activity);
1776 }
1777 }
1778 }
Bob Leee5408332009-09-04 18:31:17 -07001779
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 private final void handleNewIntent(NewIntentData data) {
1781 performNewIntents(data.token, data.intents);
1782 }
1783
1784 private final void handleReceiver(ReceiverData data) {
1785 // If we are getting ready to gc after going to the background, well
1786 // we are back active so skip it.
1787 unscheduleGcIdler();
1788
1789 String component = data.intent.getComponent().getClassName();
1790
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001791 LoadedApk packageInfo = getPackageInfoNoCheck(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001792 data.info.applicationInfo);
1793
1794 IActivityManager mgr = ActivityManagerNative.getDefault();
1795
1796 BroadcastReceiver receiver = null;
1797 try {
1798 java.lang.ClassLoader cl = packageInfo.getClassLoader();
1799 data.intent.setExtrasClassLoader(cl);
1800 if (data.resultExtras != null) {
1801 data.resultExtras.setClassLoader(cl);
1802 }
1803 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
1804 } catch (Exception e) {
1805 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001806 if (DEBUG_BROADCAST) Slog.i(TAG,
1807 "Finishing failed broadcast to " + data.intent.getComponent());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001808 mgr.finishReceiver(mAppThread.asBinder(), data.resultCode,
1809 data.resultData, data.resultExtras, data.resultAbort);
1810 } catch (RemoteException ex) {
1811 }
1812 throw new RuntimeException(
1813 "Unable to instantiate receiver " + component
1814 + ": " + e.toString(), e);
1815 }
1816
1817 try {
Dianne Hackborn0be1f782009-11-09 12:30:12 -08001818 Application app = packageInfo.makeApplication(false, mInstrumentation);
Bob Leee5408332009-09-04 18:31:17 -07001819
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001820 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001821 TAG, "Performing receive of " + data.intent
1822 + ": app=" + app
1823 + ", appName=" + app.getPackageName()
1824 + ", pkg=" + packageInfo.getPackageName()
1825 + ", comp=" + data.intent.getComponent().toShortString()
1826 + ", dir=" + packageInfo.getAppDir());
1827
Dianne Hackborn21556372010-02-04 16:34:40 -08001828 ContextImpl context = (ContextImpl)app.getBaseContext();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001829 receiver.setOrderedHint(true);
1830 receiver.setResult(data.resultCode, data.resultData,
1831 data.resultExtras);
1832 receiver.setOrderedHint(data.sync);
1833 receiver.onReceive(context.getReceiverRestrictedContext(),
1834 data.intent);
1835 } catch (Exception e) {
1836 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001837 if (DEBUG_BROADCAST) Slog.i(TAG,
1838 "Finishing failed broadcast to " + data.intent.getComponent());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001839 mgr.finishReceiver(mAppThread.asBinder(), data.resultCode,
1840 data.resultData, data.resultExtras, data.resultAbort);
1841 } catch (RemoteException ex) {
1842 }
1843 if (!mInstrumentation.onException(receiver, e)) {
1844 throw new RuntimeException(
1845 "Unable to start receiver " + component
1846 + ": " + e.toString(), e);
1847 }
1848 }
1849
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07001850 QueuedWork.waitToFinish();
1851
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001852 try {
1853 if (data.sync) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001854 if (DEBUG_BROADCAST) Slog.i(TAG,
1855 "Finishing ordered broadcast to " + data.intent.getComponent());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001856 mgr.finishReceiver(
1857 mAppThread.asBinder(), receiver.getResultCode(),
1858 receiver.getResultData(), receiver.getResultExtras(false),
1859 receiver.getAbortBroadcast());
1860 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001861 if (DEBUG_BROADCAST) Slog.i(TAG,
1862 "Finishing broadcast to " + data.intent.getComponent());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001863 mgr.finishReceiver(mAppThread.asBinder(), 0, null, null, false);
1864 }
1865 } catch (RemoteException ex) {
1866 }
1867 }
1868
Christopher Tate181fafa2009-05-14 11:12:14 -07001869 // Instantiate a BackupAgent and tell it that it's alive
1870 private final void handleCreateBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001871 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07001872
1873 // no longer idle; we have backup work to do
1874 unscheduleGcIdler();
1875
1876 // instantiate the BackupAgent class named in the manifest
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001877 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07001878 String packageName = packageInfo.mPackageName;
1879 if (mBackupAgents.get(packageName) != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001880 Slog.d(TAG, "BackupAgent " + " for " + packageName
Christopher Tate181fafa2009-05-14 11:12:14 -07001881 + " already exists");
1882 return;
1883 }
Bob Leee5408332009-09-04 18:31:17 -07001884
Christopher Tate181fafa2009-05-14 11:12:14 -07001885 BackupAgent agent = null;
1886 String classname = data.appInfo.backupAgentName;
1887 if (classname == null) {
1888 if (data.backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08001889 Slog.e(TAG, "Attempted incremental backup but no defined agent for "
Christopher Tate181fafa2009-05-14 11:12:14 -07001890 + packageName);
1891 return;
1892 }
1893 classname = "android.app.FullBackupAgent";
1894 }
1895 try {
Christopher Tated1475e02009-07-09 15:36:17 -07001896 IBinder binder = null;
1897 try {
1898 java.lang.ClassLoader cl = packageInfo.getClassLoader();
1899 agent = (BackupAgent) cl.loadClass(data.appInfo.backupAgentName).newInstance();
1900
1901 // set up the agent's context
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001902 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing BackupAgent "
Christopher Tated1475e02009-07-09 15:36:17 -07001903 + data.appInfo.backupAgentName);
1904
Dianne Hackborn21556372010-02-04 16:34:40 -08001905 ContextImpl context = new ContextImpl();
Christopher Tated1475e02009-07-09 15:36:17 -07001906 context.init(packageInfo, null, this);
1907 context.setOuterContext(agent);
1908 agent.attach(context);
1909
1910 agent.onCreate();
1911 binder = agent.onBind();
1912 mBackupAgents.put(packageName, agent);
1913 } catch (Exception e) {
1914 // If this is during restore, fail silently; otherwise go
1915 // ahead and let the user see the crash.
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08001916 Slog.e(TAG, "Agent threw during creation: " + e);
Christopher Tated1475e02009-07-09 15:36:17 -07001917 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE) {
1918 throw e;
1919 }
1920 // falling through with 'binder' still null
1921 }
Christopher Tate181fafa2009-05-14 11:12:14 -07001922
1923 // tell the OS that we're live now
Christopher Tate181fafa2009-05-14 11:12:14 -07001924 try {
1925 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder);
1926 } catch (RemoteException e) {
1927 // nothing to do.
1928 }
Christopher Tate181fafa2009-05-14 11:12:14 -07001929 } catch (Exception e) {
1930 throw new RuntimeException("Unable to create BackupAgent "
1931 + data.appInfo.backupAgentName + ": " + e.toString(), e);
1932 }
1933 }
1934
1935 // Tear down a BackupAgent
1936 private final void handleDestroyBackupAgent(CreateBackupAgentData data) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001937 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
Bob Leee5408332009-09-04 18:31:17 -07001938
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001939 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07001940 String packageName = packageInfo.mPackageName;
1941 BackupAgent agent = mBackupAgents.get(packageName);
1942 if (agent != null) {
1943 try {
1944 agent.onDestroy();
1945 } catch (Exception e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08001946 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo);
Christopher Tate181fafa2009-05-14 11:12:14 -07001947 e.printStackTrace();
1948 }
1949 mBackupAgents.remove(packageName);
1950 } else {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08001951 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data);
Christopher Tate181fafa2009-05-14 11:12:14 -07001952 }
1953 }
1954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001955 private final void handleCreateService(CreateServiceData data) {
1956 // If we are getting ready to gc after going to the background, well
1957 // we are back active so skip it.
1958 unscheduleGcIdler();
1959
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07001960 LoadedApk packageInfo = getPackageInfoNoCheck(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001961 data.info.applicationInfo);
1962 Service service = null;
1963 try {
1964 java.lang.ClassLoader cl = packageInfo.getClassLoader();
1965 service = (Service) cl.loadClass(data.info.name).newInstance();
1966 } catch (Exception e) {
1967 if (!mInstrumentation.onException(service, e)) {
1968 throw new RuntimeException(
1969 "Unable to instantiate service " + data.info.name
1970 + ": " + e.toString(), e);
1971 }
1972 }
1973
1974 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07001975 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001976
Dianne Hackborn21556372010-02-04 16:34:40 -08001977 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001978 context.init(packageInfo, null, this);
1979
Dianne Hackborn0be1f782009-11-09 12:30:12 -08001980 Application app = packageInfo.makeApplication(false, mInstrumentation);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001981 context.setOuterContext(service);
1982 service.attach(context, this, data.info.name, data.token, app,
1983 ActivityManagerNative.getDefault());
1984 service.onCreate();
1985 mServices.put(data.token, service);
1986 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07001987 ActivityManagerNative.getDefault().serviceDoneExecuting(
1988 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001989 } catch (RemoteException e) {
1990 // nothing to do.
1991 }
1992 } catch (Exception e) {
1993 if (!mInstrumentation.onException(service, e)) {
1994 throw new RuntimeException(
1995 "Unable to create service " + data.info.name
1996 + ": " + e.toString(), e);
1997 }
1998 }
1999 }
2000
2001 private final void handleBindService(BindServiceData data) {
2002 Service s = mServices.get(data.token);
2003 if (s != null) {
2004 try {
2005 data.intent.setExtrasClassLoader(s.getClassLoader());
2006 try {
2007 if (!data.rebind) {
2008 IBinder binder = s.onBind(data.intent);
2009 ActivityManagerNative.getDefault().publishService(
2010 data.token, data.intent, binder);
2011 } else {
2012 s.onRebind(data.intent);
2013 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002014 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002016 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 } catch (RemoteException ex) {
2018 }
2019 } catch (Exception e) {
2020 if (!mInstrumentation.onException(s, e)) {
2021 throw new RuntimeException(
2022 "Unable to bind to service " + s
2023 + " with " + data.intent + ": " + e.toString(), e);
2024 }
2025 }
2026 }
2027 }
2028
2029 private final void handleUnbindService(BindServiceData data) {
2030 Service s = mServices.get(data.token);
2031 if (s != null) {
2032 try {
2033 data.intent.setExtrasClassLoader(s.getClassLoader());
2034 boolean doRebind = s.onUnbind(data.intent);
2035 try {
2036 if (doRebind) {
2037 ActivityManagerNative.getDefault().unbindFinished(
2038 data.token, data.intent, doRebind);
2039 } else {
2040 ActivityManagerNative.getDefault().serviceDoneExecuting(
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002041 data.token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002042 }
2043 } catch (RemoteException ex) {
2044 }
2045 } catch (Exception e) {
2046 if (!mInstrumentation.onException(s, e)) {
2047 throw new RuntimeException(
2048 "Unable to unbind to service " + s
2049 + " with " + data.intent + ": " + e.toString(), e);
2050 }
2051 }
2052 }
2053 }
2054
Dianne Hackborn625ac272010-09-17 18:29:22 -07002055 private void handleDumpService(DumpComponentInfo info) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002056 try {
Dianne Hackborn625ac272010-09-17 18:29:22 -07002057 Service s = mServices.get(info.token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002058 if (s != null) {
2059 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd));
2060 s.dump(info.fd, pw, info.args);
2061 pw.close();
2062 }
2063 } finally {
2064 synchronized (info) {
2065 info.dumped = true;
2066 info.notifyAll();
2067 }
2068 }
2069 }
2070
Dianne Hackborn625ac272010-09-17 18:29:22 -07002071 private void handleDumpActivity(DumpComponentInfo info) {
2072 try {
2073 ActivityClientRecord r = mActivities.get(info.token);
2074 if (r != null && r.activity != null) {
2075 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd));
2076 r.activity.dump(info.fd, pw, info.args);
2077 pw.close();
2078 }
2079 } finally {
2080 synchronized (info) {
2081 info.dumped = true;
2082 info.notifyAll();
2083 }
2084 }
2085 }
2086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002087 private final void handleServiceArgs(ServiceArgsData data) {
2088 Service s = mServices.get(data.token);
2089 if (s != null) {
2090 try {
2091 if (data.args != null) {
2092 data.args.setExtrasClassLoader(s.getClassLoader());
2093 }
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002094 int res = s.onStartCommand(data.args, data.flags, data.startId);
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002095
2096 QueuedWork.waitToFinish();
2097
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002098 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002099 ActivityManagerNative.getDefault().serviceDoneExecuting(
2100 data.token, 1, data.startId, res);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002101 } catch (RemoteException e) {
2102 // nothing to do.
2103 }
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08002104 ensureJitEnabled();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002105 } catch (Exception e) {
2106 if (!mInstrumentation.onException(s, e)) {
2107 throw new RuntimeException(
2108 "Unable to start service " + s
2109 + " with " + data.args + ": " + e.toString(), e);
2110 }
2111 }
2112 }
2113 }
2114
2115 private final void handleStopService(IBinder token) {
2116 Service s = mServices.remove(token);
2117 if (s != null) {
2118 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002119 if (localLOGV) Slog.v(TAG, "Destroying service " + s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002120 s.onDestroy();
2121 Context context = s.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002122 if (context instanceof ContextImpl) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002123 final String who = s.getClassName();
Dianne Hackborn21556372010-02-04 16:34:40 -08002124 ((ContextImpl) context).scheduleFinalCleanup(who, "Service");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002125 }
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07002126
2127 QueuedWork.waitToFinish();
2128
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002129 try {
Dianne Hackbornf6f9f2d2009-08-21 16:26:03 -07002130 ActivityManagerNative.getDefault().serviceDoneExecuting(
2131 token, 0, 0, 0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002132 } catch (RemoteException e) {
2133 // nothing to do.
2134 }
2135 } catch (Exception e) {
2136 if (!mInstrumentation.onException(s, e)) {
2137 throw new RuntimeException(
2138 "Unable to stop service " + s
2139 + ": " + e.toString(), e);
2140 }
2141 }
2142 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002143 //Slog.i(TAG, "Running services: " + mServices);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 }
2145
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002146 public final ActivityClientRecord performResumeActivity(IBinder token,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002147 boolean clearHide) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002148 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002149 if (localLOGV) Slog.v(TAG, "Performing resume of " + r
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 + " finished=" + r.activity.mFinished);
2151 if (r != null && !r.activity.mFinished) {
2152 if (clearHide) {
2153 r.hideForNow = false;
2154 r.activity.mStartedActivity = false;
2155 }
2156 try {
2157 if (r.pendingIntents != null) {
2158 deliverNewIntents(r, r.pendingIntents);
2159 r.pendingIntents = null;
2160 }
2161 if (r.pendingResults != null) {
2162 deliverResults(r, r.pendingResults);
2163 r.pendingResults = null;
2164 }
2165 r.activity.performResume();
2166
Bob Leee5408332009-09-04 18:31:17 -07002167 EventLog.writeEvent(LOG_ON_RESUME_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002168 r.activity.getComponentName().getClassName());
Bob Leee5408332009-09-04 18:31:17 -07002169
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002170 r.paused = false;
2171 r.stopped = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002172 r.state = null;
2173 } catch (Exception e) {
2174 if (!mInstrumentation.onException(r.activity, e)) {
2175 throw new RuntimeException(
2176 "Unable to resume activity "
2177 + r.intent.getComponent().toShortString()
2178 + ": " + e.toString(), e);
2179 }
2180 }
2181 }
2182 return r;
2183 }
2184
2185 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward) {
2186 // If we are getting ready to gc after going to the background, well
2187 // we are back active so skip it.
2188 unscheduleGcIdler();
2189
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002190 ActivityClientRecord r = performResumeActivity(token, clearHide);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002191
2192 if (r != null) {
2193 final Activity a = r.activity;
2194
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002195 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 TAG, "Resume " + r + " started activity: " +
2197 a.mStartedActivity + ", hideForNow: " + r.hideForNow
2198 + ", finished: " + a.mFinished);
2199
2200 final int forwardBit = isForward ?
2201 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
Bob Leee5408332009-09-04 18:31:17 -07002202
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002203 // If the window hasn't yet been added to the window manager,
2204 // and this guy didn't finish itself or start another activity,
2205 // then go ahead and add the window.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002206 boolean willBeVisible = !a.mStartedActivity;
2207 if (!willBeVisible) {
2208 try {
2209 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
2210 a.getActivityToken());
2211 } catch (RemoteException e) {
2212 }
2213 }
2214 if (r.window == null && !a.mFinished && willBeVisible) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 r.window = r.activity.getWindow();
2216 View decor = r.window.getDecorView();
2217 decor.setVisibility(View.INVISIBLE);
2218 ViewManager wm = a.getWindowManager();
2219 WindowManager.LayoutParams l = r.window.getAttributes();
2220 a.mDecor = decor;
2221 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
2222 l.softInputMode |= forwardBit;
2223 if (a.mVisibleFromClient) {
2224 a.mWindowAdded = true;
2225 wm.addView(decor, l);
2226 }
2227
2228 // If the window has already been added, but during resume
2229 // we started another activity, then don't yet make the
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002230 // window visible.
2231 } else if (!willBeVisible) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002232 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002233 TAG, "Launch " + r + " mStartedActivity set");
2234 r.hideForNow = true;
2235 }
2236
2237 // The window is now visible if it has been added, we are not
2238 // simply finishing, and we are not starting another activity.
Dianne Hackborn061d58a2010-03-12 15:07:06 -08002239 if (!r.activity.mFinished && willBeVisible
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002240 && r.activity.mDecor != null && !r.hideForNow) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002241 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002242 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002243 + r.activityInfo.name + " with newConfig " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 performConfigurationChanged(r.activity, r.newConfig);
2245 r.newConfig = null;
2246 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002247 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002248 + isForward);
2249 WindowManager.LayoutParams l = r.window.getAttributes();
2250 if ((l.softInputMode
2251 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
2252 != forwardBit) {
2253 l.softInputMode = (l.softInputMode
2254 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
2255 | forwardBit;
Dianne Hackbornc1e605e2009-09-25 17:18:15 -07002256 if (r.activity.mVisibleFromClient) {
2257 ViewManager wm = a.getWindowManager();
2258 View decor = r.window.getDecorView();
2259 wm.updateViewLayout(decor, l);
2260 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 }
2262 r.activity.mVisibleFromServer = true;
2263 mNumVisibleActivities++;
2264 if (r.activity.mVisibleFromClient) {
2265 r.activity.makeVisible();
2266 }
2267 }
2268
2269 r.nextIdle = mNewActivities;
2270 mNewActivities = r;
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002271 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002272 TAG, "Scheduling idle handler for " + r);
2273 Looper.myQueue().addIdleHandler(new Idler());
2274
2275 } else {
2276 // If an exception was thrown when trying to resume, then
2277 // just end this activity.
2278 try {
2279 ActivityManagerNative.getDefault()
2280 .finishActivity(token, Activity.RESULT_CANCELED, null);
2281 } catch (RemoteException ex) {
2282 }
2283 }
2284 }
2285
2286 private int mThumbnailWidth = -1;
2287 private int mThumbnailHeight = -1;
2288
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002289 private final Bitmap createThumbnailBitmap(ActivityClientRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 Bitmap thumbnail = null;
2291 try {
2292 int w = mThumbnailWidth;
2293 int h;
2294 if (w < 0) {
2295 Resources res = r.activity.getResources();
2296 mThumbnailHeight = h =
2297 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height);
2298
2299 mThumbnailWidth = w =
2300 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width);
2301 } else {
2302 h = mThumbnailHeight;
2303 }
2304
Jim Miller0b2a6d02010-07-13 18:01:29 -07002305 // On platforms where we don't want thumbnails, set dims to (0,0)
2306 if ((w > 0) && (h > 0)) {
2307 View topView = r.activity.getWindow().getDecorView();
2308
2309 // Maximize bitmap by capturing in native aspect.
2310 if (topView.getWidth() >= topView.getHeight()) {
2311 thumbnail = Bitmap.createBitmap(w, h, THUMBNAIL_FORMAT);
2312 } else {
2313 thumbnail = Bitmap.createBitmap(h, w, THUMBNAIL_FORMAT);
2314 }
2315
2316 thumbnail.eraseColor(0);
2317 Canvas cv = new Canvas(thumbnail);
2318 if (!r.activity.onCreateThumbnail(thumbnail, cv)) {
2319 thumbnail = null;
2320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002321 }
Jim Miller0b2a6d02010-07-13 18:01:29 -07002322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002323 } catch (Exception e) {
2324 if (!mInstrumentation.onException(r.activity, e)) {
2325 throw new RuntimeException(
2326 "Unable to create thumbnail of "
2327 + r.intent.getComponent().toShortString()
2328 + ": " + e.toString(), e);
2329 }
2330 thumbnail = null;
2331 }
2332
2333 return thumbnail;
2334 }
2335
2336 private final void handlePauseActivity(IBinder token, boolean finished,
2337 boolean userLeaving, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002338 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002339 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002340 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002341 if (userLeaving) {
2342 performUserLeavingActivity(r);
2343 }
Bob Leee5408332009-09-04 18:31:17 -07002344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002345 r.activity.mConfigChangeFlags |= configChanges;
2346 Bundle state = performPauseActivity(token, finished, true);
2347
2348 // Tell the activity manager we have paused.
2349 try {
2350 ActivityManagerNative.getDefault().activityPaused(token, state);
2351 } catch (RemoteException ex) {
2352 }
2353 }
2354 }
2355
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002356 final void performUserLeavingActivity(ActivityClientRecord r) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002357 mInstrumentation.callActivityOnUserLeaving(r.activity);
2358 }
2359
2360 final Bundle performPauseActivity(IBinder token, boolean finished,
2361 boolean saveState) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002362 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002363 return r != null ? performPauseActivity(r, finished, saveState) : null;
2364 }
2365
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002366 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002367 boolean saveState) {
2368 if (r.paused) {
2369 if (r.activity.mFinished) {
2370 // If we are finishing, we won't call onResume() in certain cases.
2371 // So here we likewise don't want to call onPause() if the activity
2372 // isn't resumed.
2373 return null;
2374 }
2375 RuntimeException e = new RuntimeException(
2376 "Performing pause of activity that is not resumed: "
2377 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002378 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002379 }
2380 Bundle state = null;
2381 if (finished) {
2382 r.activity.mFinished = true;
2383 }
2384 try {
2385 // Next have the activity save its current state and managed dialogs...
2386 if (!r.activity.mFinished && saveState) {
2387 state = new Bundle();
2388 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state);
2389 r.state = state;
2390 }
2391 // Now we are idle.
2392 r.activity.mCalled = false;
2393 mInstrumentation.callActivityOnPause(r.activity);
2394 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, r.activity.getComponentName().getClassName());
2395 if (!r.activity.mCalled) {
2396 throw new SuperNotCalledException(
2397 "Activity " + r.intent.getComponent().toShortString() +
2398 " did not call through to super.onPause()");
2399 }
2400
2401 } catch (SuperNotCalledException e) {
2402 throw e;
2403
2404 } catch (Exception e) {
2405 if (!mInstrumentation.onException(r.activity, e)) {
2406 throw new RuntimeException(
2407 "Unable to pause activity "
2408 + r.intent.getComponent().toShortString()
2409 + ": " + e.toString(), e);
2410 }
2411 }
2412 r.paused = true;
2413 return state;
2414 }
2415
2416 final void performStopActivity(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002417 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002418 performStopActivityInner(r, null, false);
2419 }
2420
2421 private static class StopInfo {
2422 Bitmap thumbnail;
2423 CharSequence description;
2424 }
2425
2426 private final class ProviderRefCount {
2427 public int count;
2428 ProviderRefCount(int pCount) {
2429 count = pCount;
2430 }
2431 }
2432
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002433 private final void performStopActivityInner(ActivityClientRecord r,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002434 StopInfo info, boolean keepShown) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002435 if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002436 if (r != null) {
2437 if (!keepShown && r.stopped) {
2438 if (r.activity.mFinished) {
2439 // If we are finishing, we won't call onResume() in certain
2440 // cases. So here we likewise don't want to call onStop()
2441 // if the activity isn't resumed.
2442 return;
2443 }
2444 RuntimeException e = new RuntimeException(
2445 "Performing stop of activity that is not resumed: "
2446 + r.intent.getComponent().toShortString());
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08002447 Slog.e(TAG, e.getMessage(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002448 }
2449
2450 if (info != null) {
2451 try {
2452 // First create a thumbnail for the activity...
Jim Miller0b2a6d02010-07-13 18:01:29 -07002453 info.thumbnail = createThumbnailBitmap(r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002454 info.description = r.activity.onCreateDescription();
2455 } catch (Exception e) {
2456 if (!mInstrumentation.onException(r.activity, e)) {
2457 throw new RuntimeException(
2458 "Unable to save state of activity "
2459 + r.intent.getComponent().toShortString()
2460 + ": " + e.toString(), e);
2461 }
2462 }
2463 }
2464
2465 if (!keepShown) {
2466 try {
2467 // Now we are idle.
2468 r.activity.performStop();
2469 } catch (Exception e) {
2470 if (!mInstrumentation.onException(r.activity, e)) {
2471 throw new RuntimeException(
2472 "Unable to stop activity "
2473 + r.intent.getComponent().toShortString()
2474 + ": " + e.toString(), e);
2475 }
2476 }
2477 r.stopped = true;
2478 }
2479
2480 r.paused = true;
2481 }
2482 }
2483
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002484 private final void updateVisibility(ActivityClientRecord r, boolean show) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002485 View v = r.activity.mDecor;
2486 if (v != null) {
2487 if (show) {
2488 if (!r.activity.mVisibleFromServer) {
2489 r.activity.mVisibleFromServer = true;
2490 mNumVisibleActivities++;
2491 if (r.activity.mVisibleFromClient) {
2492 r.activity.makeVisible();
2493 }
2494 }
2495 if (r.newConfig != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002496 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002497 + r.activityInfo.name + " with new config " + r.newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002498 performConfigurationChanged(r.activity, r.newConfig);
2499 r.newConfig = null;
2500 }
2501 } else {
2502 if (r.activity.mVisibleFromServer) {
2503 r.activity.mVisibleFromServer = false;
2504 mNumVisibleActivities--;
2505 v.setVisibility(View.INVISIBLE);
2506 }
2507 }
2508 }
2509 }
2510
2511 private final void handleStopActivity(IBinder token, boolean show, int configChanges) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002512 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002513 r.activity.mConfigChangeFlags |= configChanges;
2514
2515 StopInfo info = new StopInfo();
2516 performStopActivityInner(r, info, show);
2517
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002518 if (localLOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002519 TAG, "Finishing stop of " + r + ": show=" + show
2520 + " win=" + r.window);
2521
2522 updateVisibility(r, show);
Bob Leee5408332009-09-04 18:31:17 -07002523
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002524 // Tell activity manager we have been stopped.
2525 try {
2526 ActivityManagerNative.getDefault().activityStopped(
2527 r.token, info.thumbnail, info.description);
2528 } catch (RemoteException ex) {
2529 }
2530 }
2531
2532 final void performRestartActivity(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002533 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002534 if (r.stopped) {
2535 r.activity.performRestart();
2536 r.stopped = false;
2537 }
2538 }
2539
2540 private final void handleWindowVisibility(IBinder token, boolean show) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002541 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002542 if (!show && !r.stopped) {
2543 performStopActivityInner(r, null, show);
2544 } else if (show && r.stopped) {
2545 // If we are getting ready to gc after going to the background, well
2546 // we are back active so skip it.
2547 unscheduleGcIdler();
2548
2549 r.activity.performRestart();
2550 r.stopped = false;
2551 }
2552 if (r.activity.mDecor != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002553 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002554 TAG, "Handle window " + r + " visibility: " + show);
2555 updateVisibility(r, show);
2556 }
2557 }
2558
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002559 private final void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002560 final int N = results.size();
2561 for (int i=0; i<N; i++) {
2562 ResultInfo ri = results.get(i);
2563 try {
2564 if (ri.mData != null) {
2565 ri.mData.setExtrasClassLoader(r.activity.getClassLoader());
2566 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002567 if (DEBUG_RESULTS) Slog.v(TAG,
Chris Tate8a7dc172009-03-24 20:11:42 -07002568 "Delivering result to activity " + r + " : " + ri);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002569 r.activity.dispatchActivityResult(ri.mResultWho,
2570 ri.mRequestCode, ri.mResultCode, ri.mData);
2571 } catch (Exception e) {
2572 if (!mInstrumentation.onException(r.activity, e)) {
2573 throw new RuntimeException(
2574 "Failure delivering result " + ri + " to activity "
2575 + r.intent.getComponent().toShortString()
2576 + ": " + e.toString(), e);
2577 }
2578 }
2579 }
2580 }
2581
2582 private final void handleSendResult(ResultData res) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002583 ActivityClientRecord r = mActivities.get(res.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002584 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002585 if (r != null) {
2586 final boolean resumed = !r.paused;
2587 if (!r.activity.mFinished && r.activity.mDecor != null
2588 && r.hideForNow && resumed) {
2589 // We had hidden the activity because it started another
2590 // one... we have gotten a result back and we are not
2591 // paused, so make sure our window is visible.
2592 updateVisibility(r, true);
2593 }
2594 if (resumed) {
2595 try {
2596 // Now we are idle.
2597 r.activity.mCalled = false;
2598 mInstrumentation.callActivityOnPause(r.activity);
2599 if (!r.activity.mCalled) {
2600 throw new SuperNotCalledException(
2601 "Activity " + r.intent.getComponent().toShortString()
2602 + " did not call through to super.onPause()");
2603 }
2604 } catch (SuperNotCalledException e) {
2605 throw e;
2606 } catch (Exception e) {
2607 if (!mInstrumentation.onException(r.activity, e)) {
2608 throw new RuntimeException(
2609 "Unable to pause activity "
2610 + r.intent.getComponent().toShortString()
2611 + ": " + e.toString(), e);
2612 }
2613 }
2614 }
2615 deliverResults(r, res.results);
2616 if (resumed) {
2617 mInstrumentation.callActivityOnResume(r.activity);
2618 }
2619 }
2620 }
2621
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002622 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002623 return performDestroyActivity(token, finishing, 0, false);
2624 }
2625
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002626 private final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002627 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002628 ActivityClientRecord r = mActivities.get(token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002629 if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002630 if (r != null) {
2631 r.activity.mConfigChangeFlags |= configChanges;
2632 if (finishing) {
2633 r.activity.mFinished = true;
2634 }
Jeff Hamilton3d32f6e2010-04-01 00:04:16 -05002635 if (getNonConfigInstance) {
2636 r.activity.mChangingConfigurations = true;
2637 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002638 if (!r.paused) {
2639 try {
2640 r.activity.mCalled = false;
2641 mInstrumentation.callActivityOnPause(r.activity);
Bob Leee5408332009-09-04 18:31:17 -07002642 EventLog.writeEvent(LOG_ON_PAUSE_CALLED,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002643 r.activity.getComponentName().getClassName());
2644 if (!r.activity.mCalled) {
2645 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002646 "Activity " + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002647 + " did not call through to super.onPause()");
2648 }
2649 } catch (SuperNotCalledException e) {
2650 throw e;
2651 } catch (Exception e) {
2652 if (!mInstrumentation.onException(r.activity, e)) {
2653 throw new RuntimeException(
2654 "Unable to pause activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002655 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002656 + ": " + e.toString(), e);
2657 }
2658 }
2659 r.paused = true;
2660 }
2661 if (!r.stopped) {
2662 try {
2663 r.activity.performStop();
2664 } catch (SuperNotCalledException e) {
2665 throw e;
2666 } catch (Exception e) {
2667 if (!mInstrumentation.onException(r.activity, e)) {
2668 throw new RuntimeException(
2669 "Unable to stop activity "
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002670 + safeToComponentShortString(r.intent)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002671 + ": " + e.toString(), e);
2672 }
2673 }
2674 r.stopped = true;
2675 }
2676 if (getNonConfigInstance) {
2677 try {
Dianne Hackbornb4bc78b2010-05-12 18:59:50 -07002678 r.lastNonConfigurationInstances
2679 = r.activity.retainNonConfigurationInstances();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002680 } catch (Exception e) {
2681 if (!mInstrumentation.onException(r.activity, e)) {
2682 throw new RuntimeException(
2683 "Unable to retain activity "
2684 + r.intent.getComponent().toShortString()
2685 + ": " + e.toString(), e);
2686 }
2687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002688 }
2689 try {
2690 r.activity.mCalled = false;
Dianne Hackborn2dedce62010-04-15 14:45:25 -07002691 mInstrumentation.callActivityOnDestroy(r.activity);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002692 if (!r.activity.mCalled) {
2693 throw new SuperNotCalledException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002694 "Activity " + safeToComponentShortString(r.intent) +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002695 " did not call through to super.onDestroy()");
2696 }
2697 if (r.window != null) {
2698 r.window.closeAllPanels();
2699 }
2700 } catch (SuperNotCalledException e) {
2701 throw e;
2702 } catch (Exception e) {
2703 if (!mInstrumentation.onException(r.activity, e)) {
2704 throw new RuntimeException(
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002705 "Unable to destroy activity " + safeToComponentShortString(r.intent)
2706 + ": " + e.toString(), e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002707 }
2708 }
2709 }
2710 mActivities.remove(token);
2711
2712 return r;
2713 }
2714
Mitsuru Oshimad9aef732009-06-16 20:20:50 -07002715 private static String safeToComponentShortString(Intent intent) {
2716 ComponentName component = intent.getComponent();
2717 return component == null ? "[Unknown]" : component.toShortString();
2718 }
2719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002720 private final void handleDestroyActivity(IBinder token, boolean finishing,
2721 int configChanges, boolean getNonConfigInstance) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002722 ActivityClientRecord r = performDestroyActivity(token, finishing,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002723 configChanges, getNonConfigInstance);
2724 if (r != null) {
2725 WindowManager wm = r.activity.getWindowManager();
2726 View v = r.activity.mDecor;
2727 if (v != null) {
2728 if (r.activity.mVisibleFromServer) {
2729 mNumVisibleActivities--;
2730 }
2731 IBinder wtoken = v.getWindowToken();
2732 if (r.activity.mWindowAdded) {
2733 wm.removeViewImmediate(v);
2734 }
2735 if (wtoken != null) {
2736 WindowManagerImpl.getDefault().closeAll(wtoken,
2737 r.activity.getClass().getName(), "Activity");
2738 }
2739 r.activity.mDecor = null;
2740 }
2741 WindowManagerImpl.getDefault().closeAll(token,
2742 r.activity.getClass().getName(), "Activity");
2743
2744 // Mocked out contexts won't be participating in the normal
2745 // process lifecycle, but if we're running with a proper
2746 // ApplicationContext we need to have it tear down things
2747 // cleanly.
2748 Context c = r.activity.getBaseContext();
Dianne Hackborn21556372010-02-04 16:34:40 -08002749 if (c instanceof ContextImpl) {
2750 ((ContextImpl) c).scheduleFinalCleanup(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002751 r.activity.getClass().getName(), "Activity");
2752 }
2753 }
2754 if (finishing) {
2755 try {
2756 ActivityManagerNative.getDefault().activityDestroyed(token);
2757 } catch (RemoteException ex) {
2758 // If the system process has died, it's game over for everyone.
2759 }
2760 }
2761 }
2762
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002763 private final void handleRelaunchActivity(ActivityClientRecord tmp, int configChanges) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002764 // If we are getting ready to gc after going to the background, well
2765 // we are back active so skip it.
2766 unscheduleGcIdler();
2767
2768 Configuration changedConfig = null;
Bob Leee5408332009-09-04 18:31:17 -07002769
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002770 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002771 + tmp.token + " with configChanges=0x"
2772 + Integer.toHexString(configChanges));
2773
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002774 // First: make sure we have the most recent configuration and most
2775 // recent version of the activity, or skip it if some previous call
2776 // had taken a more recent version.
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002777 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002778 int N = mRelaunchingActivities.size();
2779 IBinder token = tmp.token;
2780 tmp = null;
2781 for (int i=0; i<N; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002782 ActivityClientRecord r = mRelaunchingActivities.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783 if (r.token == token) {
2784 tmp = r;
2785 mRelaunchingActivities.remove(i);
2786 i--;
2787 N--;
2788 }
2789 }
Bob Leee5408332009-09-04 18:31:17 -07002790
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002791 if (tmp == null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002792 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002793 return;
2794 }
Bob Leee5408332009-09-04 18:31:17 -07002795
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002796 if (mPendingConfiguration != null) {
2797 changedConfig = mPendingConfiguration;
2798 mPendingConfiguration = null;
2799 }
2800 }
Bob Leee5408332009-09-04 18:31:17 -07002801
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08002802 if (tmp.createdConfig != null) {
2803 // If the activity manager is passing us its current config,
2804 // assume that is really what we want regardless of what we
2805 // may have pending.
2806 if (mConfiguration == null
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002807 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration)
2808 && mConfiguration.diff(tmp.createdConfig) != 0)) {
2809 if (changedConfig == null
2810 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
2811 changedConfig = tmp.createdConfig;
2812 }
Dianne Hackborn871ecdc2009-12-11 15:24:33 -08002813 }
2814 }
2815
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002816 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002817 + tmp.token + ": changedConfig=" + changedConfig);
2818
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002819 // If there was a pending configuration change, execute it first.
2820 if (changedConfig != null) {
2821 handleConfigurationChanged(changedConfig);
2822 }
Bob Leee5408332009-09-04 18:31:17 -07002823
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002824 ActivityClientRecord r = mActivities.get(tmp.token);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002825 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002826 if (r == null) {
2827 return;
2828 }
Bob Leee5408332009-09-04 18:31:17 -07002829
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002830 r.activity.mConfigChangeFlags |= configChanges;
Christopher Tateb70f3df2009-04-07 16:07:59 -07002831 Intent currentIntent = r.activity.mIntent;
Bob Leee5408332009-09-04 18:31:17 -07002832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833 Bundle savedState = null;
2834 if (!r.paused) {
2835 savedState = performPauseActivity(r.token, false, true);
2836 }
Bob Leee5408332009-09-04 18:31:17 -07002837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002838 handleDestroyActivity(r.token, false, configChanges, true);
Bob Leee5408332009-09-04 18:31:17 -07002839
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002840 r.activity = null;
2841 r.window = null;
2842 r.hideForNow = false;
2843 r.nextIdle = null;
The Android Open Source Project10592532009-03-18 17:39:46 -07002844 // Merge any pending results and pending intents; don't just replace them
2845 if (tmp.pendingResults != null) {
2846 if (r.pendingResults == null) {
2847 r.pendingResults = tmp.pendingResults;
2848 } else {
2849 r.pendingResults.addAll(tmp.pendingResults);
2850 }
2851 }
2852 if (tmp.pendingIntents != null) {
2853 if (r.pendingIntents == null) {
2854 r.pendingIntents = tmp.pendingIntents;
2855 } else {
2856 r.pendingIntents.addAll(tmp.pendingIntents);
2857 }
2858 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002859 r.startsNotResumed = tmp.startsNotResumed;
2860 if (savedState != null) {
2861 r.state = savedState;
2862 }
Bob Leee5408332009-09-04 18:31:17 -07002863
Christopher Tateb70f3df2009-04-07 16:07:59 -07002864 handleLaunchActivity(r, currentIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002865 }
2866
2867 private final void handleRequestThumbnail(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002868 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002869 Bitmap thumbnail = createThumbnailBitmap(r);
2870 CharSequence description = null;
2871 try {
2872 description = r.activity.onCreateDescription();
2873 } catch (Exception e) {
2874 if (!mInstrumentation.onException(r.activity, e)) {
2875 throw new RuntimeException(
2876 "Unable to create description of activity "
2877 + r.intent.getComponent().toShortString()
2878 + ": " + e.toString(), e);
2879 }
2880 }
2881 //System.out.println("Reporting top thumbnail " + thumbnail);
2882 try {
2883 ActivityManagerNative.getDefault().reportThumbnail(
2884 token, thumbnail, description);
2885 } catch (RemoteException ex) {
2886 }
2887 }
2888
2889 ArrayList<ComponentCallbacks> collectComponentCallbacksLocked(
2890 boolean allActivities, Configuration newConfig) {
2891 ArrayList<ComponentCallbacks> callbacks
2892 = new ArrayList<ComponentCallbacks>();
Bob Leee5408332009-09-04 18:31:17 -07002893
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002894 if (mActivities.size() > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002895 Iterator<ActivityClientRecord> it = mActivities.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002896 while (it.hasNext()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002897 ActivityClientRecord ar = it.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002898 Activity a = ar.activity;
2899 if (a != null) {
2900 if (!ar.activity.mFinished && (allActivities ||
2901 (a != null && !ar.paused))) {
2902 // If the activity is currently resumed, its configuration
2903 // needs to change right now.
2904 callbacks.add(a);
2905 } else if (newConfig != null) {
2906 // Otherwise, we will tell it about the change
2907 // the next time it is resumed or shown. Note that
2908 // the activity manager may, before then, decide the
2909 // activity needs to be destroyed to handle its new
2910 // configuration.
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002911 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Setting activity "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002912 + ar.activityInfo.name + " newConfig=" + newConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002913 ar.newConfig = newConfig;
2914 }
2915 }
2916 }
2917 }
2918 if (mServices.size() > 0) {
2919 Iterator<Service> it = mServices.values().iterator();
2920 while (it.hasNext()) {
2921 callbacks.add(it.next());
2922 }
2923 }
2924 synchronized (mProviderMap) {
2925 if (mLocalProviders.size() > 0) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07002926 Iterator<ProviderClientRecord> it = mLocalProviders.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002927 while (it.hasNext()) {
2928 callbacks.add(it.next().mLocalProvider);
2929 }
2930 }
2931 }
2932 final int N = mAllApplications.size();
2933 for (int i=0; i<N; i++) {
2934 callbacks.add(mAllApplications.get(i));
2935 }
Bob Leee5408332009-09-04 18:31:17 -07002936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002937 return callbacks;
2938 }
Bob Leee5408332009-09-04 18:31:17 -07002939
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002940 private final void performConfigurationChanged(
2941 ComponentCallbacks cb, Configuration config) {
2942 // Only for Activity objects, check that they actually call up to their
2943 // superclass implementation. ComponentCallbacks is an interface, so
2944 // we check the runtime type and act accordingly.
2945 Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
2946 if (activity != null) {
2947 activity.mCalled = false;
2948 }
Bob Leee5408332009-09-04 18:31:17 -07002949
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002950 boolean shouldChangeConfig = false;
2951 if ((activity == null) || (activity.mCurrentConfig == null)) {
2952 shouldChangeConfig = true;
2953 } else {
Bob Leee5408332009-09-04 18:31:17 -07002954
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002955 // If the new config is the same as the config this Activity
2956 // is already running with then don't bother calling
2957 // onConfigurationChanged
2958 int diff = activity.mCurrentConfig.diff(config);
2959 if (diff != 0) {
Bob Leee5408332009-09-04 18:31:17 -07002960
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002961 // If this activity doesn't handle any of the config changes
2962 // then don't bother calling onConfigurationChanged as we're
2963 // going to destroy it.
2964 if ((~activity.mActivityInfo.configChanges & diff) == 0) {
2965 shouldChangeConfig = true;
2966 }
2967 }
2968 }
Bob Leee5408332009-09-04 18:31:17 -07002969
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002970 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb
Dianne Hackborndc6b6352009-09-30 14:20:09 -07002971 + ": shouldChangeConfig=" + shouldChangeConfig);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002972 if (shouldChangeConfig) {
2973 cb.onConfigurationChanged(config);
Bob Leee5408332009-09-04 18:31:17 -07002974
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002975 if (activity != null) {
2976 if (!activity.mCalled) {
2977 throw new SuperNotCalledException(
2978 "Activity " + activity.getLocalClassName() +
2979 " did not call through to super.onConfigurationChanged()");
2980 }
2981 activity.mConfigChangeFlags = 0;
2982 activity.mCurrentConfig = new Configuration(config);
2983 }
2984 }
2985 }
2986
Dianne Hackbornae078162010-03-18 11:29:37 -07002987 final boolean applyConfigurationToResourcesLocked(Configuration config) {
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002988 if (mResConfiguration == null) {
2989 mResConfiguration = new Configuration();
2990 }
2991 if (!mResConfiguration.isOtherSeqNewer(config)) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07002992 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq="
Dianne Hackborn694f79b2010-03-17 19:44:59 -07002993 + mResConfiguration.seq + ", newSeq=" + config.seq);
Dianne Hackbornae078162010-03-18 11:29:37 -07002994 return false;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002995 }
Dianne Hackbornae078162010-03-18 11:29:37 -07002996 int changes = mResConfiguration.updateFrom(config);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002997 DisplayMetrics dm = getDisplayMetricsLocked(true);
Bob Leee5408332009-09-04 18:31:17 -07002998
Dianne Hackborne36d6e22010-02-17 19:46:25 -08002999 // set it for java, this also affects newly created Resources
3000 if (config.locale != null) {
3001 Locale.setDefault(config.locale);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003002 }
Bob Leee5408332009-09-04 18:31:17 -07003003
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003004 Resources.updateSystemConfiguration(config, dm);
Bob Leee5408332009-09-04 18:31:17 -07003005
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003006 ContextImpl.ApplicationPackageManager.configurationChanged();
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003007 //Slog.i(TAG, "Configuration changed in " + currentPackageName());
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003008
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003009 Iterator<WeakReference<Resources>> it =
3010 mActiveResources.values().iterator();
3011 //Iterator<Map.Entry<String, WeakReference<Resources>>> it =
3012 // mActiveResources.entrySet().iterator();
3013 while (it.hasNext()) {
3014 WeakReference<Resources> v = it.next();
3015 Resources r = v.get();
3016 if (r != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003017 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources "
Dianne Hackborn694f79b2010-03-17 19:44:59 -07003018 + r + " config to: " + config);
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003019 r.updateConfiguration(config, dm);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003020 //Slog.i(TAG, "Updated app resources " + v.getKey()
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003021 // + " " + r + ": " + r.getConfiguration());
3022 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003023 //Slog.i(TAG, "Removing old resources " + v.getKey());
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003024 it.remove();
3025 }
3026 }
Dianne Hackbornae078162010-03-18 11:29:37 -07003027
3028 return changes != 0;
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003029 }
3030
3031 final void handleConfigurationChanged(Configuration config) {
3032
3033 ArrayList<ComponentCallbacks> callbacks = null;
3034
3035 synchronized (mPackages) {
3036 if (mPendingConfiguration != null) {
3037 if (!mPendingConfiguration.isOtherSeqNewer(config)) {
3038 config = mPendingConfiguration;
3039 }
3040 mPendingConfiguration = null;
3041 }
3042
3043 if (config == null) {
3044 return;
3045 }
3046
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003047 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: "
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003048 + config);
3049
3050 applyConfigurationToResourcesLocked(config);
3051
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003052 if (mConfiguration == null) {
3053 mConfiguration = new Configuration();
3054 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003055 if (!mConfiguration.isOtherSeqNewer(config)) {
3056 return;
3057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003058 mConfiguration.updateFrom(config);
Bob Leee5408332009-09-04 18:31:17 -07003059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003060 callbacks = collectComponentCallbacksLocked(false, config);
3061 }
Bob Leee5408332009-09-04 18:31:17 -07003062
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003063 if (callbacks != null) {
3064 final int N = callbacks.size();
3065 for (int i=0; i<N; i++) {
3066 performConfigurationChanged(callbacks.get(i), config);
3067 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003068 }
3069 }
3070
3071 final void handleActivityConfigurationChanged(IBinder token) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003072 ActivityClientRecord r = mActivities.get(token);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003073 if (r == null || r.activity == null) {
3074 return;
3075 }
Bob Leee5408332009-09-04 18:31:17 -07003076
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003077 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: "
Dianne Hackborndc6b6352009-09-30 14:20:09 -07003078 + r.activityInfo.name);
3079
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003080 performConfigurationChanged(r.activity, mConfiguration);
3081 }
3082
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003083 final void handleProfilerControl(boolean start, ProfilerControlData pcd) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003084 if (start) {
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003085 try {
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003086 Debug.startMethodTracing(pcd.path, pcd.fd.getFileDescriptor(),
3087 8 * 1024 * 1024, 0);
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003088 } catch (RuntimeException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003089 Slog.w(TAG, "Profiling failed on path " + pcd.path
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003090 + " -- can the process access this path?");
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003091 } finally {
3092 try {
3093 pcd.fd.close();
3094 } catch (IOException e) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003095 Slog.w(TAG, "Failure closing profile fd", e);
Dianne Hackborn9c8dd552009-06-23 19:22:52 -07003096 }
The Android Open Source Projectf5b4b982009-03-05 20:00:43 -08003097 }
3098 } else {
3099 Debug.stopMethodTracing();
3100 }
3101 }
Bob Leee5408332009-09-04 18:31:17 -07003102
Andy McFadden824c5102010-07-09 16:26:57 -07003103 final void handleDumpHeap(boolean managed, DumpHeapData dhd) {
3104 if (managed) {
3105 try {
3106 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor());
3107 } catch (IOException e) {
3108 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path
3109 + " -- can the process access this path?");
3110 } finally {
3111 try {
3112 dhd.fd.close();
3113 } catch (IOException e) {
3114 Slog.w(TAG, "Failure closing profile fd", e);
3115 }
3116 }
3117 } else {
Andy McFadden06a6b552010-07-13 16:28:09 -07003118 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor());
Andy McFadden824c5102010-07-09 16:26:57 -07003119 }
3120 }
3121
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003122 final void handleDispatchPackageBroadcast(int cmd, String[] packages) {
3123 boolean hasPkgInfo = false;
3124 if (packages != null) {
3125 for (int i=packages.length-1; i>=0; i--) {
3126 //Slog.i(TAG, "Cleaning old package: " + packages[i]);
3127 if (!hasPkgInfo) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003128 WeakReference<LoadedApk> ref;
Dianne Hackborn4416c3d2010-05-04 17:22:49 -07003129 ref = mPackages.get(packages[i]);
3130 if (ref != null && ref.get() != null) {
3131 hasPkgInfo = true;
3132 } else {
3133 ref = mResourcePackages.get(packages[i]);
3134 if (ref != null && ref.get() != null) {
3135 hasPkgInfo = true;
3136 }
3137 }
3138 }
3139 mPackages.remove(packages[i]);
3140 mResourcePackages.remove(packages[i]);
3141 }
3142 }
3143 ContextImpl.ApplicationPackageManager.handlePackageBroadcast(cmd, packages,
3144 hasPkgInfo);
3145 }
3146
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003147 final void handleLowMemory() {
3148 ArrayList<ComponentCallbacks> callbacks
3149 = new ArrayList<ComponentCallbacks>();
3150
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003151 synchronized (mPackages) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003152 callbacks = collectComponentCallbacksLocked(true, null);
3153 }
Bob Leee5408332009-09-04 18:31:17 -07003154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003155 final int N = callbacks.size();
3156 for (int i=0; i<N; i++) {
3157 callbacks.get(i).onLowMemory();
3158 }
3159
Chris Tatece229052009-03-25 16:44:52 -07003160 // Ask SQLite to free up as much memory as it can, mostly from its page caches.
3161 if (Process.myUid() != Process.SYSTEM_UID) {
3162 int sqliteReleased = SQLiteDatabase.releaseMemory();
3163 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased);
3164 }
Bob Leee5408332009-09-04 18:31:17 -07003165
Mike Reedcaf0df12009-04-27 14:32:05 -04003166 // Ask graphics to free up as much as possible (font/image caches)
3167 Canvas.freeCaches();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003168
3169 BinderInternal.forceGc("mem");
3170 }
3171
3172 private final void handleBindApplication(AppBindData data) {
3173 mBoundApplication = data;
3174 mConfiguration = new Configuration(data.config);
3175
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003176 // send up app name; do this *before* waiting for debugger
Christopher Tate8ee038d2009-11-06 11:30:20 -08003177 Process.setArgV0(data.processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003178 android.ddm.DdmHandleAppName.setAppName(data.processName);
3179
3180 /*
3181 * Before spawning a new process, reset the time zone to be the system time zone.
3182 * This needs to be done because the system time zone could have changed after the
3183 * the spawning of this process. Without doing this this process would have the incorrect
3184 * system time zone.
3185 */
3186 TimeZone.setDefault(null);
3187
3188 /*
3189 * Initialize the default locale in this process for the reasons we set the time zone.
3190 */
3191 Locale.setDefault(data.config.locale);
3192
Suchi Amalapurapuc9843292009-06-24 17:02:25 -07003193 /*
3194 * Update the system configuration since its preloaded and might not
3195 * reflect configuration changes. The configuration object passed
3196 * in AppBindData can be safely assumed to be up to date
3197 */
3198 Resources.getSystem().updateConfiguration(mConfiguration, null);
3199
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003200 data.info = getPackageInfoNoCheck(data.appInfo);
3201
Dianne Hackborn96e240f2009-07-26 17:42:30 -07003202 /**
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07003203 * For system applications on userdebug/eng builds, log stack
3204 * traces of disk and network access to dropbox for analysis.
3205 */
Brad Fitzpatrickad13b982010-07-14 12:35:53 -07003206 if ((data.appInfo.flags &
3207 (ApplicationInfo.FLAG_SYSTEM |
Brad Fitzpatrick50d66f92010-09-13 21:29:05 -07003208 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
3209 StrictMode.conditionallyEnableDebugLogging();
Brad Fitzpatrick438d0592010-06-10 12:19:19 -07003210 }
3211
3212 /**
Dianne Hackborn96e240f2009-07-26 17:42:30 -07003213 * Switch this process to density compatibility mode if needed.
3214 */
3215 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES)
3216 == 0) {
3217 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT);
3218 }
Bob Leee5408332009-09-04 18:31:17 -07003219
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003220 if (data.debugMode != IApplicationThread.DEBUG_OFF) {
3221 // XXX should have option to change the port.
3222 Debug.changeDebugPort(8100);
3223 if (data.debugMode == IApplicationThread.DEBUG_WAIT) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003224 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003225 + " is waiting for the debugger on port 8100...");
3226
3227 IActivityManager mgr = ActivityManagerNative.getDefault();
3228 try {
3229 mgr.showWaitingForDebugger(mAppThread, true);
3230 } catch (RemoteException ex) {
3231 }
3232
3233 Debug.waitForDebugger();
3234
3235 try {
3236 mgr.showWaitingForDebugger(mAppThread, false);
3237 } catch (RemoteException ex) {
3238 }
3239
3240 } else {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003241 Slog.w(TAG, "Application " + data.info.getPackageName()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003242 + " can be debugged on port 8100...");
3243 }
3244 }
3245
3246 if (data.instrumentationName != null) {
Dianne Hackborn21556372010-02-04 16:34:40 -08003247 ContextImpl appContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003248 appContext.init(data.info, null, this);
3249 InstrumentationInfo ii = null;
3250 try {
3251 ii = appContext.getPackageManager().
3252 getInstrumentationInfo(data.instrumentationName, 0);
3253 } catch (PackageManager.NameNotFoundException e) {
3254 }
3255 if (ii == null) {
3256 throw new RuntimeException(
3257 "Unable to find instrumentation info for: "
3258 + data.instrumentationName);
3259 }
3260
3261 mInstrumentationAppDir = ii.sourceDir;
3262 mInstrumentationAppPackage = ii.packageName;
3263 mInstrumentedAppDir = data.info.getAppDir();
3264
3265 ApplicationInfo instrApp = new ApplicationInfo();
3266 instrApp.packageName = ii.packageName;
3267 instrApp.sourceDir = ii.sourceDir;
3268 instrApp.publicSourceDir = ii.publicSourceDir;
3269 instrApp.dataDir = ii.dataDir;
Kenny Root85387d72010-08-26 10:13:11 -07003270 instrApp.nativeLibraryDir = ii.nativeLibraryDir;
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003271 LoadedApk pi = getPackageInfo(instrApp,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003272 appContext.getClassLoader(), false, true);
Dianne Hackborn21556372010-02-04 16:34:40 -08003273 ContextImpl instrContext = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003274 instrContext.init(pi, null, this);
3275
3276 try {
3277 java.lang.ClassLoader cl = instrContext.getClassLoader();
3278 mInstrumentation = (Instrumentation)
3279 cl.loadClass(data.instrumentationName.getClassName()).newInstance();
3280 } catch (Exception e) {
3281 throw new RuntimeException(
3282 "Unable to instantiate instrumentation "
3283 + data.instrumentationName + ": " + e.toString(), e);
3284 }
3285
3286 mInstrumentation.init(this, instrContext, appContext,
3287 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher);
3288
3289 if (data.profileFile != null && !ii.handleProfiling) {
3290 data.handlingProfiling = true;
3291 File file = new File(data.profileFile);
3292 file.getParentFile().mkdirs();
3293 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024);
3294 }
3295
3296 try {
3297 mInstrumentation.onCreate(data.instrumentationArgs);
3298 }
3299 catch (Exception e) {
3300 throw new RuntimeException(
3301 "Exception thrown in onCreate() of "
3302 + data.instrumentationName + ": " + e.toString(), e);
3303 }
3304
3305 } else {
3306 mInstrumentation = new Instrumentation();
3307 }
3308
Christopher Tate181fafa2009-05-14 11:12:14 -07003309 // If the app is being launched for full backup or restore, bring it up in
3310 // a restricted environment with the base application class.
Dianne Hackborn0be1f782009-11-09 12:30:12 -08003311 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003312 mInitialApplication = app;
3313
3314 List<ProviderInfo> providers = data.providers;
3315 if (providers != null) {
3316 installContentProviders(app, providers);
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08003317 // For process that contain content providers, we want to
3318 // ensure that the JIT is enabled "at some point".
3319 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003320 }
3321
3322 try {
3323 mInstrumentation.callApplicationOnCreate(app);
3324 } catch (Exception e) {
3325 if (!mInstrumentation.onException(app, e)) {
3326 throw new RuntimeException(
3327 "Unable to create application " + app.getClass().getName()
3328 + ": " + e.toString(), e);
3329 }
3330 }
3331 }
3332
3333 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) {
3334 IActivityManager am = ActivityManagerNative.getDefault();
3335 if (mBoundApplication.profileFile != null && mBoundApplication.handlingProfiling) {
3336 Debug.stopMethodTracing();
3337 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003338 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault()
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003339 // + ", app thr: " + mAppThread);
3340 try {
3341 am.finishInstrumentation(mAppThread, resultCode, results);
3342 } catch (RemoteException ex) {
3343 }
3344 }
3345
3346 private final void installContentProviders(
3347 Context context, List<ProviderInfo> providers) {
3348 final ArrayList<IActivityManager.ContentProviderHolder> results =
3349 new ArrayList<IActivityManager.ContentProviderHolder>();
3350
3351 Iterator<ProviderInfo> i = providers.iterator();
3352 while (i.hasNext()) {
3353 ProviderInfo cpi = i.next();
3354 StringBuilder buf = new StringBuilder(128);
3355 buf.append("Publishing provider ");
3356 buf.append(cpi.authority);
3357 buf.append(": ");
3358 buf.append(cpi.name);
3359 Log.i(TAG, buf.toString());
3360 IContentProvider cp = installProvider(context, null, cpi, false);
3361 if (cp != null) {
3362 IActivityManager.ContentProviderHolder cph =
3363 new IActivityManager.ContentProviderHolder(cpi);
3364 cph.provider = cp;
3365 results.add(cph);
3366 // Don't ever unload this provider from the process.
3367 synchronized(mProviderMap) {
3368 mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
3369 }
3370 }
3371 }
3372
3373 try {
3374 ActivityManagerNative.getDefault().publishContentProviders(
3375 getApplicationThread(), results);
3376 } catch (RemoteException ex) {
3377 }
3378 }
3379
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003380 private final IContentProvider getExistingProvider(Context context, String name) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003381 synchronized(mProviderMap) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003382 final ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003383 if (pr != null) {
3384 return pr.mProvider;
3385 }
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003386 return null;
3387 }
3388 }
3389
3390 private final IContentProvider getProvider(Context context, String name) {
3391 IContentProvider existing = getExistingProvider(context, name);
3392 if (existing != null) {
3393 return existing;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003394 }
3395
3396 IActivityManager.ContentProviderHolder holder = null;
3397 try {
3398 holder = ActivityManagerNative.getDefault().getContentProvider(
3399 getApplicationThread(), name);
3400 } catch (RemoteException ex) {
3401 }
3402 if (holder == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003403 Slog.e(TAG, "Failed to find provider info for " + name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003404 return null;
3405 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003406
3407 IContentProvider prov = installProvider(context, holder.provider,
3408 holder.info, true);
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003409 //Slog.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003410 if (holder.noReleaseNeeded || holder.provider == null) {
3411 // We are not going to release the provider if it is an external
3412 // provider that doesn't care about being released, or if it is
3413 // a local provider running in this process.
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003414 //Slog.i(TAG, "*** NO RELEASE NEEDED");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003415 synchronized(mProviderMap) {
3416 mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(10000));
3417 }
3418 }
3419 return prov;
3420 }
3421
3422 public final IContentProvider acquireProvider(Context c, String name) {
3423 IContentProvider provider = getProvider(c, name);
3424 if(provider == null)
3425 return null;
3426 IBinder jBinder = provider.asBinder();
3427 synchronized(mProviderMap) {
3428 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3429 if(prc == null) {
3430 mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
3431 } else {
3432 prc.count++;
3433 } //end else
3434 } //end synchronized
3435 return provider;
3436 }
3437
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003438 public final IContentProvider acquireExistingProvider(Context c, String name) {
3439 IContentProvider provider = getExistingProvider(c, name);
3440 if(provider == null)
3441 return null;
3442 IBinder jBinder = provider.asBinder();
3443 synchronized(mProviderMap) {
3444 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3445 if(prc == null) {
3446 mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
3447 } else {
3448 prc.count++;
3449 } //end else
3450 } //end synchronized
3451 return provider;
3452 }
3453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003454 public final boolean releaseProvider(IContentProvider provider) {
3455 if(provider == null) {
3456 return false;
3457 }
3458 IBinder jBinder = provider.asBinder();
3459 synchronized(mProviderMap) {
3460 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3461 if(prc == null) {
Dianne Hackborncca1f0e2010-09-26 18:34:53 -07003462 if(localLOGV) Slog.v(TAG, "releaseProvider::Weird shouldn't be here");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003463 return false;
3464 } else {
3465 prc.count--;
3466 if(prc.count == 0) {
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003467 // Schedule the actual remove asynchronously, since we
3468 // don't know the context this will be called in.
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003469 // TODO: it would be nice to post a delayed message, so
3470 // if we come back and need the same provider quickly
3471 // we will still have it available.
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003472 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, provider);
3473 mH.sendMessage(msg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003474 } //end if
3475 } //end else
3476 } //end synchronized
3477 return true;
3478 }
3479
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003480 final void completeRemoveProvider(IContentProvider provider) {
3481 IBinder jBinder = provider.asBinder();
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003482 String name = null;
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003483 synchronized(mProviderMap) {
3484 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
3485 if(prc != null && prc.count == 0) {
3486 mProviderRefCountMap.remove(jBinder);
3487 //invoke removeProvider to dereference provider
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003488 name = removeProviderLocked(provider);
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003489 }
3490 }
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003491
3492 if (name != null) {
3493 try {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003494 if(localLOGV) Slog.v(TAG, "removeProvider::Invoking " +
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003495 "ActivityManagerNative.removeContentProvider(" + name);
3496 ActivityManagerNative.getDefault().removeContentProvider(
3497 getApplicationThread(), name);
3498 } catch (RemoteException e) {
3499 //do nothing content provider object is dead any way
3500 } //end catch
3501 }
Dianne Hackborn9bfb7072009-09-22 11:37:40 -07003502 }
3503
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003504 public final String removeProviderLocked(IContentProvider provider) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003505 if (provider == null) {
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003506 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003507 }
3508 IBinder providerBinder = provider.asBinder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003509
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003510 String name = null;
3511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003512 // remove the provider from mProviderMap
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003513 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003514 while (iter.hasNext()) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003515 ProviderClientRecord pr = iter.next();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003516 IBinder myBinder = pr.mProvider.asBinder();
3517 if (myBinder == providerBinder) {
3518 //find if its published by this process itself
3519 if(pr.mLocalProvider != null) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003520 if(localLOGV) Slog.i(TAG, "removeProvider::found local provider returning");
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003521 return name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003522 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003523 if(localLOGV) Slog.v(TAG, "removeProvider::Not local provider Unlinking " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003524 "death recipient");
3525 //content provider is in another process
3526 myBinder.unlinkToDeath(pr, 0);
3527 iter.remove();
3528 //invoke remove only once for the very first name seen
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003529 if(name == null) {
3530 name = pr.mName;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003531 }
3532 } //end if myBinder
3533 } //end while iter
Dianne Hackborn0c3154d2009-10-06 17:18:05 -07003534
3535 return name;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003536 }
3537
3538 final void removeDeadProvider(String name, IContentProvider provider) {
3539 synchronized(mProviderMap) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003540 ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003541 if (pr.mProvider.asBinder() == provider.asBinder()) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003542 Slog.i(TAG, "Removing dead content provider: " + name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003543 ProviderClientRecord removed = mProviderMap.remove(name);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07003544 if (removed != null) {
3545 removed.mProvider.asBinder().unlinkToDeath(removed, 0);
3546 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003547 }
3548 }
3549 }
3550
3551 final void removeDeadProviderLocked(String name, IContentProvider provider) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003552 ProviderClientRecord pr = mProviderMap.get(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003553 if (pr.mProvider.asBinder() == provider.asBinder()) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003554 Slog.i(TAG, "Removing dead content provider: " + name);
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003555 ProviderClientRecord removed = mProviderMap.remove(name);
Suchi Amalapurapufff2fda2009-06-30 21:36:16 -07003556 if (removed != null) {
3557 removed.mProvider.asBinder().unlinkToDeath(removed, 0);
3558 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003559 }
3560 }
3561
3562 private final IContentProvider installProvider(Context context,
3563 IContentProvider provider, ProviderInfo info, boolean noisy) {
3564 ContentProvider localProvider = null;
3565 if (provider == null) {
3566 if (noisy) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003567 Slog.d(TAG, "Loading provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003568 + info.name);
3569 }
3570 Context c = null;
3571 ApplicationInfo ai = info.applicationInfo;
3572 if (context.getPackageName().equals(ai.packageName)) {
3573 c = context;
3574 } else if (mInitialApplication != null &&
3575 mInitialApplication.getPackageName().equals(ai.packageName)) {
3576 c = mInitialApplication;
3577 } else {
3578 try {
3579 c = context.createPackageContext(ai.packageName,
3580 Context.CONTEXT_INCLUDE_CODE);
3581 } catch (PackageManager.NameNotFoundException e) {
3582 }
3583 }
3584 if (c == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003585 Slog.w(TAG, "Unable to get context for package " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003586 ai.packageName +
3587 " while loading content provider " +
3588 info.name);
3589 return null;
3590 }
3591 try {
3592 final java.lang.ClassLoader cl = c.getClassLoader();
3593 localProvider = (ContentProvider)cl.
3594 loadClass(info.name).newInstance();
3595 provider = localProvider.getIContentProvider();
3596 if (provider == null) {
Dianne Hackbornc9421ba2010-03-11 22:23:46 -08003597 Slog.e(TAG, "Failed to instantiate class " +
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003598 info.name + " from sourceDir " +
3599 info.applicationInfo.sourceDir);
3600 return null;
3601 }
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003602 if (Config.LOGV) Slog.v(
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003603 TAG, "Instantiating local provider " + info.name);
3604 // XXX Need to create the correct context for this provider.
3605 localProvider.attachInfo(c, info);
3606 } catch (java.lang.Exception e) {
3607 if (!mInstrumentation.onException(null, e)) {
3608 throw new RuntimeException(
3609 "Unable to get provider " + info.name
3610 + ": " + e.toString(), e);
3611 }
3612 return null;
3613 }
3614 } else if (localLOGV) {
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003615 Slog.v(TAG, "Installing external provider " + info.authority + ": "
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003616 + info.name);
3617 }
3618
3619 synchronized (mProviderMap) {
3620 // Cache the pointer for the remote provider.
3621 String names[] = PATTERN_SEMICOLON.split(info.authority);
3622 for (int i=0; i<names.length; i++) {
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003623 ProviderClientRecord pr = new ProviderClientRecord(names[i], provider,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003624 localProvider);
3625 try {
3626 provider.asBinder().linkToDeath(pr, 0);
3627 mProviderMap.put(names[i], pr);
3628 } catch (RemoteException e) {
3629 return null;
3630 }
3631 }
3632 if (localProvider != null) {
3633 mLocalProviders.put(provider.asBinder(),
Dianne Hackborn01e4cfc2010-06-24 15:07:24 -07003634 new ProviderClientRecord(null, provider, localProvider));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003635 }
3636 }
3637
3638 return provider;
3639 }
3640
3641 private final void attach(boolean system) {
3642 sThreadLocal.set(this);
3643 mSystemThread = system;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003644 if (!system) {
Dianne Hackborn2a9094d2010-02-03 19:20:09 -08003645 ViewRoot.addFirstDrawHandler(new Runnable() {
3646 public void run() {
3647 ensureJitEnabled();
3648 }
3649 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003650 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>");
3651 RuntimeInit.setApplicationObject(mAppThread.asBinder());
3652 IActivityManager mgr = ActivityManagerNative.getDefault();
3653 try {
3654 mgr.attachApplication(mAppThread);
3655 } catch (RemoteException ex) {
3656 }
3657 } else {
3658 // Don't set application object here -- if the system crashes,
3659 // we can't display an alert, we just want to die die die.
3660 android.ddm.DdmHandleAppName.setAppName("system_process");
3661 try {
3662 mInstrumentation = new Instrumentation();
Dianne Hackborn21556372010-02-04 16:34:40 -08003663 ContextImpl context = new ContextImpl();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003664 context.init(getSystemContext().mPackageInfo, null, this);
3665 Application app = Instrumentation.newApplication(Application.class, context);
3666 mAllApplications.add(app);
3667 mInitialApplication = app;
3668 app.onCreate();
3669 } catch (Exception e) {
3670 throw new RuntimeException(
3671 "Unable to instantiate Application():" + e.toString(), e);
3672 }
3673 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003674
3675 ViewRoot.addConfigCallback(new ComponentCallbacks() {
3676 public void onConfigurationChanged(Configuration newConfig) {
3677 synchronized (mPackages) {
Dianne Hackbornae078162010-03-18 11:29:37 -07003678 // We need to apply this change to the resources
3679 // immediately, because upon returning the view
3680 // hierarchy will be informed about it.
3681 if (applyConfigurationToResourcesLocked(newConfig)) {
3682 // This actually changed the resources! Tell
3683 // everyone about it.
3684 if (mPendingConfiguration == null ||
3685 mPendingConfiguration.isOtherSeqNewer(newConfig)) {
3686 mPendingConfiguration = newConfig;
3687
3688 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig);
3689 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003690 }
3691 }
Dianne Hackborne36d6e22010-02-17 19:46:25 -08003692 }
3693 public void onLowMemory() {
3694 }
3695 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003696 }
3697
3698 private final void detach()
3699 {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003700 sThreadLocal.set(null);
3701 }
3702
3703 public static final ActivityThread systemMain() {
Romain Guy52339202010-09-03 16:04:46 -07003704 HardwareRenderer.disable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003705 ActivityThread thread = new ActivityThread();
3706 thread.attach(true);
3707 return thread;
3708 }
3709
3710 public final void installSystemProviders(List providers) {
3711 if (providers != null) {
3712 installContentProviders(mInitialApplication,
3713 (List<ProviderInfo>)providers);
3714 }
3715 }
3716
3717 public static final void main(String[] args) {
Bob Leee5408332009-09-04 18:31:17 -07003718 SamplingProfilerIntegration.start();
3719
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003720 Process.setArgV0("<pre-initialized>");
3721
3722 Looper.prepareMainLooper();
Brad Fitzpatrick333b8cb2010-08-26 12:04:57 -07003723 if (sMainThreadHandler == null) {
3724 sMainThreadHandler = new Handler();
3725 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003726
3727 ActivityThread thread = new ActivityThread();
3728 thread.attach(false);
3729
Dianne Hackborn287952c2010-09-22 22:34:31 -07003730 if (false) {
3731 Looper.myLooper().setMessageLogging(new
3732 LogPrinter(Log.DEBUG, "ActivityThread"));
3733 }
3734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003735 Looper.loop();
3736
3737 if (Process.supportsProcesses()) {
3738 throw new RuntimeException("Main thread loop unexpectedly exited");
3739 }
3740
3741 thread.detach();
Bob Leeeec2f412009-09-10 11:01:24 +02003742 String name = (thread.mInitialApplication != null)
3743 ? thread.mInitialApplication.getPackageName()
3744 : "<unknown>";
Dianne Hackborn399cccb2010-04-13 22:57:49 -07003745 Slog.i(TAG, "Main thread of " + name + " is now exiting");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003746 }
3747}