ActivityThread.java revision 48d0d1886731ff19ed3fb47a5997be5df0d1bba8
1/* 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 19import static android.view.DisplayAdjustments.DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN; 20 21import android.app.backup.BackupAgent; 22import android.content.BroadcastReceiver; 23import android.content.ComponentCallbacks2; 24import android.content.ComponentName; 25import android.content.ContentProvider; 26import android.content.Context; 27import android.content.IContentProvider; 28import android.content.Intent; 29import android.content.IIntentReceiver; 30import android.content.pm.ActivityInfo; 31import android.content.pm.ApplicationInfo; 32import android.content.pm.IPackageManager; 33import android.content.pm.InstrumentationInfo; 34import android.content.pm.PackageInfo; 35import android.content.pm.PackageManager; 36import android.content.pm.PackageManager.NameNotFoundException; 37import android.content.pm.ProviderInfo; 38import android.content.pm.ServiceInfo; 39import android.content.res.AssetManager; 40import android.content.res.CompatibilityInfo; 41import android.content.res.Configuration; 42import android.content.res.Resources; 43import android.database.sqlite.SQLiteDatabase; 44import android.database.sqlite.SQLiteDebug; 45import android.database.sqlite.SQLiteDebug.DbStats; 46import android.graphics.Bitmap; 47import android.graphics.Canvas; 48import android.hardware.display.DisplayManagerGlobal; 49import android.net.IConnectivityManager; 50import android.net.Proxy; 51import android.net.ProxyProperties; 52import android.opengl.GLUtils; 53import android.os.AsyncTask; 54import android.os.Binder; 55import android.os.Bundle; 56import android.os.Debug; 57import android.os.DropBoxManager; 58import android.os.Environment; 59import android.os.Handler; 60import android.os.IBinder; 61import android.os.Looper; 62import android.os.Message; 63import android.os.MessageQueue; 64import android.os.ParcelFileDescriptor; 65import android.os.Process; 66import android.os.RemoteException; 67import android.os.ServiceManager; 68import android.os.StrictMode; 69import android.os.SystemClock; 70import android.os.SystemProperties; 71import android.os.Trace; 72import android.os.UserHandle; 73import android.util.AndroidRuntimeException; 74import android.util.DisplayMetrics; 75import android.util.EventLog; 76import android.util.Log; 77import android.util.LogPrinter; 78import android.util.PrintWriterPrinter; 79import android.util.Slog; 80import android.view.DisplayAdjustments; 81import android.view.Display; 82import android.view.HardwareRenderer; 83import android.view.View; 84import android.view.ViewDebug; 85import android.view.ViewManager; 86import android.view.ViewRootImpl; 87import android.view.Window; 88import android.view.WindowManager; 89import android.view.WindowManagerGlobal; 90import android.renderscript.RenderScript; 91import android.security.AndroidKeyStoreProvider; 92 93import com.android.internal.os.BinderInternal; 94import com.android.internal.os.RuntimeInit; 95import com.android.internal.os.SamplingProfilerIntegration; 96import com.android.internal.util.Objects; 97import com.android.org.conscrypt.OpenSSLSocketImpl; 98 99import java.io.File; 100import java.io.FileDescriptor; 101import java.io.FileOutputStream; 102import java.io.IOException; 103import java.io.PrintWriter; 104import java.lang.ref.WeakReference; 105import java.net.InetAddress; 106import java.security.Security; 107import java.util.ArrayList; 108import java.util.HashMap; 109import java.util.Iterator; 110import java.util.List; 111import java.util.Locale; 112import java.util.Map; 113import java.util.TimeZone; 114import java.util.regex.Pattern; 115 116import libcore.io.DropBox; 117import libcore.io.EventLogger; 118import libcore.io.IoUtils; 119 120import dalvik.system.CloseGuard; 121 122final class SuperNotCalledException extends AndroidRuntimeException { 123 public SuperNotCalledException(String msg) { 124 super(msg); 125 } 126} 127 128final class RemoteServiceException extends AndroidRuntimeException { 129 public RemoteServiceException(String msg) { 130 super(msg); 131 } 132} 133 134/** 135 * This manages the execution of the main thread in an 136 * application process, scheduling and executing activities, 137 * broadcasts, and other operations on it as the activity 138 * manager requests. 139 * 140 * {@hide} 141 */ 142public final class ActivityThread { 143 /** @hide */ 144 public static final String TAG = "ActivityThread"; 145 private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565; 146 static final boolean localLOGV = false; 147 static final boolean DEBUG_MESSAGES = false; 148 /** @hide */ 149 public static final boolean DEBUG_BROADCAST = false; 150 private static final boolean DEBUG_RESULTS = false; 151 private static final boolean DEBUG_BACKUP = false; 152 private static final boolean DEBUG_CONFIGURATION = false; 153 private static final boolean DEBUG_SERVICE = false; 154 private static final boolean DEBUG_MEMORY_TRIM = false; 155 private static final boolean DEBUG_PROVIDER = false; 156 private static final long MIN_TIME_BETWEEN_GCS = 5*1000; 157 private static final Pattern PATTERN_SEMICOLON = Pattern.compile(";"); 158 private static final int SQLITE_MEM_RELEASED_EVENT_LOG_TAG = 75003; 159 private static final int LOG_ON_PAUSE_CALLED = 30021; 160 private static final int LOG_ON_RESUME_CALLED = 30022; 161 162 static ContextImpl mSystemContext = null; 163 164 static IPackageManager sPackageManager; 165 166 final ApplicationThread mAppThread = new ApplicationThread(); 167 final Looper mLooper = Looper.myLooper(); 168 final H mH = new H(); 169 final HashMap<IBinder, ActivityClientRecord> mActivities 170 = new HashMap<IBinder, ActivityClientRecord>(); 171 // List of new activities (via ActivityRecord.nextIdle) that should 172 // be reported when next we idle. 173 ActivityClientRecord mNewActivities = null; 174 // Number of activities that are currently visible on-screen. 175 int mNumVisibleActivities = 0; 176 final HashMap<IBinder, Service> mServices 177 = new HashMap<IBinder, Service>(); 178 AppBindData mBoundApplication; 179 Profiler mProfiler; 180 int mCurDefaultDisplayDpi; 181 boolean mDensityCompatMode; 182 Configuration mConfiguration; 183 Configuration mCompatConfiguration; 184 Configuration mResConfiguration; 185 CompatibilityInfo mResCompatibilityInfo; 186 Application mInitialApplication; 187 final ArrayList<Application> mAllApplications 188 = new ArrayList<Application>(); 189 // set of instantiated backup agents, keyed by package name 190 final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>(); 191 /** Reference to singleton {@link ActivityThread} */ 192 private static ActivityThread sCurrentActivityThread; 193 Instrumentation mInstrumentation; 194 String mInstrumentationAppDir = null; 195 String mInstrumentationAppLibraryDir = null; 196 String mInstrumentationAppPackage = null; 197 String mInstrumentedAppDir = null; 198 String mInstrumentedAppLibraryDir = null; 199 boolean mSystemThread = false; 200 boolean mJitEnabled = false; 201 202 // These can be accessed by multiple threads; mPackages is the lock. 203 // XXX For now we keep around information about all packages we have 204 // seen, not removing entries from this map. 205 // NOTE: The activity and window managers need to call in to 206 // ActivityThread to do things like update resource configurations, 207 // which means this lock gets held while the activity and window managers 208 // holds their own lock. Thus you MUST NEVER call back into the activity manager 209 // or window manager or anything that depends on them while holding this lock. 210 final HashMap<String, WeakReference<LoadedApk>> mPackages 211 = new HashMap<String, WeakReference<LoadedApk>>(); 212 final HashMap<String, WeakReference<LoadedApk>> mResourcePackages 213 = new HashMap<String, WeakReference<LoadedApk>>(); 214 final HashMap<DisplayAdjustments, DisplayMetrics> mDefaultDisplayMetrics 215 = new HashMap<DisplayAdjustments, DisplayMetrics>(); 216 final HashMap<ResourcesKey, WeakReference<Resources> > mActiveResources 217 = new HashMap<ResourcesKey, WeakReference<Resources> >(); 218 final ArrayList<ActivityClientRecord> mRelaunchingActivities 219 = new ArrayList<ActivityClientRecord>(); 220 Configuration mPendingConfiguration = null; 221 222 private static final class ProviderKey { 223 final String authority; 224 final int userId; 225 226 public ProviderKey(String authority, int userId) { 227 this.authority = authority; 228 this.userId = userId; 229 } 230 231 @Override 232 public boolean equals(Object o) { 233 if (o instanceof ProviderKey) { 234 final ProviderKey other = (ProviderKey) o; 235 return Objects.equal(authority, other.authority) && userId == other.userId; 236 } 237 return false; 238 } 239 240 @Override 241 public int hashCode() { 242 return ((authority != null) ? authority.hashCode() : 0) ^ userId; 243 } 244 } 245 246 // The lock of mProviderMap protects the following variables. 247 final HashMap<ProviderKey, ProviderClientRecord> mProviderMap 248 = new HashMap<ProviderKey, ProviderClientRecord>(); 249 final HashMap<IBinder, ProviderRefCount> mProviderRefCountMap 250 = new HashMap<IBinder, ProviderRefCount>(); 251 final HashMap<IBinder, ProviderClientRecord> mLocalProviders 252 = new HashMap<IBinder, ProviderClientRecord>(); 253 final HashMap<ComponentName, ProviderClientRecord> mLocalProvidersByName 254 = new HashMap<ComponentName, ProviderClientRecord>(); 255 256 final HashMap<Activity, ArrayList<OnActivityPausedListener>> mOnPauseListeners 257 = new HashMap<Activity, ArrayList<OnActivityPausedListener>>(); 258 259 final GcIdler mGcIdler = new GcIdler(); 260 boolean mGcIdlerScheduled = false; 261 262 static Handler sMainThreadHandler; // set once in main() 263 264 Bundle mCoreSettings = null; 265 266 static final class ActivityClientRecord { 267 IBinder token; 268 int ident; 269 Intent intent; 270 Bundle state; 271 Activity activity; 272 Window window; 273 Activity parent; 274 String embeddedID; 275 Activity.NonConfigurationInstances lastNonConfigurationInstances; 276 boolean paused; 277 boolean stopped; 278 boolean hideForNow; 279 Configuration newConfig; 280 Configuration createdConfig; 281 ActivityClientRecord nextIdle; 282 283 String profileFile; 284 ParcelFileDescriptor profileFd; 285 boolean autoStopProfiler; 286 287 ActivityInfo activityInfo; 288 CompatibilityInfo compatInfo; 289 LoadedApk packageInfo; 290 291 List<ResultInfo> pendingResults; 292 List<Intent> pendingIntents; 293 294 boolean startsNotResumed; 295 boolean isForward; 296 int pendingConfigChanges; 297 boolean onlyLocalRequest; 298 299 View mPendingRemoveWindow; 300 WindowManager mPendingRemoveWindowManager; 301 302 ActivityClientRecord() { 303 parent = null; 304 embeddedID = null; 305 paused = false; 306 stopped = false; 307 hideForNow = false; 308 nextIdle = null; 309 } 310 311 public boolean isPreHoneycomb() { 312 if (activity != null) { 313 return activity.getApplicationInfo().targetSdkVersion 314 < android.os.Build.VERSION_CODES.HONEYCOMB; 315 } 316 return false; 317 } 318 319 public String toString() { 320 ComponentName componentName = intent != null ? intent.getComponent() : null; 321 return "ActivityRecord{" 322 + Integer.toHexString(System.identityHashCode(this)) 323 + " token=" + token + " " + (componentName == null 324 ? "no component name" : componentName.toShortString()) 325 + "}"; 326 } 327 } 328 329 final class ProviderClientRecord { 330 final String[] mNames; 331 final IContentProvider mProvider; 332 final ContentProvider mLocalProvider; 333 final IActivityManager.ContentProviderHolder mHolder; 334 335 ProviderClientRecord(String[] names, IContentProvider provider, 336 ContentProvider localProvider, 337 IActivityManager.ContentProviderHolder holder) { 338 mNames = names; 339 mProvider = provider; 340 mLocalProvider = localProvider; 341 mHolder = holder; 342 } 343 } 344 345 static final class NewIntentData { 346 List<Intent> intents; 347 IBinder token; 348 public String toString() { 349 return "NewIntentData{intents=" + intents + " token=" + token + "}"; 350 } 351 } 352 353 static final class ReceiverData extends BroadcastReceiver.PendingResult { 354 public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras, 355 boolean ordered, boolean sticky, IBinder token, int sendingUser) { 356 super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky, 357 token, sendingUser); 358 this.intent = intent; 359 } 360 361 Intent intent; 362 ActivityInfo info; 363 CompatibilityInfo compatInfo; 364 public String toString() { 365 return "ReceiverData{intent=" + intent + " packageName=" + 366 info.packageName + " resultCode=" + getResultCode() 367 + " resultData=" + getResultData() + " resultExtras=" 368 + getResultExtras(false) + "}"; 369 } 370 } 371 372 static final class CreateBackupAgentData { 373 ApplicationInfo appInfo; 374 CompatibilityInfo compatInfo; 375 int backupMode; 376 public String toString() { 377 return "CreateBackupAgentData{appInfo=" + appInfo 378 + " backupAgent=" + appInfo.backupAgentName 379 + " mode=" + backupMode + "}"; 380 } 381 } 382 383 static final class CreateServiceData { 384 IBinder token; 385 ServiceInfo info; 386 CompatibilityInfo compatInfo; 387 Intent intent; 388 public String toString() { 389 return "CreateServiceData{token=" + token + " className=" 390 + info.name + " packageName=" + info.packageName 391 + " intent=" + intent + "}"; 392 } 393 } 394 395 static final class BindServiceData { 396 IBinder token; 397 Intent intent; 398 boolean rebind; 399 public String toString() { 400 return "BindServiceData{token=" + token + " intent=" + intent + "}"; 401 } 402 } 403 404 static final class ServiceArgsData { 405 IBinder token; 406 boolean taskRemoved; 407 int startId; 408 int flags; 409 Intent args; 410 public String toString() { 411 return "ServiceArgsData{token=" + token + " startId=" + startId 412 + " args=" + args + "}"; 413 } 414 } 415 416 static final class AppBindData { 417 LoadedApk info; 418 String processName; 419 ApplicationInfo appInfo; 420 List<ProviderInfo> providers; 421 ComponentName instrumentationName; 422 Bundle instrumentationArgs; 423 IInstrumentationWatcher instrumentationWatcher; 424 IUiAutomationConnection instrumentationUiAutomationConnection; 425 int debugMode; 426 boolean enableOpenGlTrace; 427 boolean restrictedBackupMode; 428 boolean persistent; 429 Configuration config; 430 CompatibilityInfo compatInfo; 431 432 /** Initial values for {@link Profiler}. */ 433 String initProfileFile; 434 ParcelFileDescriptor initProfileFd; 435 boolean initAutoStopProfiler; 436 437 public String toString() { 438 return "AppBindData{appInfo=" + appInfo + "}"; 439 } 440 } 441 442 static final class Profiler { 443 String profileFile; 444 ParcelFileDescriptor profileFd; 445 boolean autoStopProfiler; 446 boolean profiling; 447 boolean handlingProfiling; 448 public void setProfiler(String file, ParcelFileDescriptor fd) { 449 if (profiling) { 450 if (fd != null) { 451 try { 452 fd.close(); 453 } catch (IOException e) { 454 // Ignore 455 } 456 } 457 return; 458 } 459 if (profileFd != null) { 460 try { 461 profileFd.close(); 462 } catch (IOException e) { 463 // Ignore 464 } 465 } 466 profileFile = file; 467 profileFd = fd; 468 } 469 public void startProfiling() { 470 if (profileFd == null || profiling) { 471 return; 472 } 473 try { 474 Debug.startMethodTracing(profileFile, profileFd.getFileDescriptor(), 475 8 * 1024 * 1024, 0); 476 profiling = true; 477 } catch (RuntimeException e) { 478 Slog.w(TAG, "Profiling failed on path " + profileFile); 479 try { 480 profileFd.close(); 481 profileFd = null; 482 } catch (IOException e2) { 483 Slog.w(TAG, "Failure closing profile fd", e2); 484 } 485 } 486 } 487 public void stopProfiling() { 488 if (profiling) { 489 profiling = false; 490 Debug.stopMethodTracing(); 491 if (profileFd != null) { 492 try { 493 profileFd.close(); 494 } catch (IOException e) { 495 } 496 } 497 profileFd = null; 498 profileFile = null; 499 } 500 } 501 } 502 503 static final class DumpComponentInfo { 504 ParcelFileDescriptor fd; 505 IBinder token; 506 String prefix; 507 String[] args; 508 } 509 510 static final class ResultData { 511 IBinder token; 512 List<ResultInfo> results; 513 public String toString() { 514 return "ResultData{token=" + token + " results" + results + "}"; 515 } 516 } 517 518 static final class ContextCleanupInfo { 519 ContextImpl context; 520 String what; 521 String who; 522 } 523 524 static final class ProfilerControlData { 525 String path; 526 ParcelFileDescriptor fd; 527 } 528 529 static final class DumpHeapData { 530 String path; 531 ParcelFileDescriptor fd; 532 } 533 534 static final class UpdateCompatibilityData { 535 String pkg; 536 CompatibilityInfo info; 537 } 538 539 static final class RequestActivityExtras { 540 IBinder activityToken; 541 IBinder requestToken; 542 int requestType; 543 } 544 545 private native void dumpGraphicsInfo(FileDescriptor fd); 546 547 private class ApplicationThread extends ApplicationThreadNative { 548 private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s %8s %8s %8s"; 549 private static final String ONE_COUNT_COLUMN = "%21s %8d"; 550 private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d"; 551 private static final String DB_INFO_FORMAT = " %8s %8s %14s %14s %s"; 552 553 // Formatting for checkin service - update version if row format changes 554 private static final int ACTIVITY_THREAD_CHECKIN_VERSION = 2; 555 556 private void updatePendingConfiguration(Configuration config) { 557 synchronized (mPackages) { 558 if (mPendingConfiguration == null || 559 mPendingConfiguration.isOtherSeqNewer(config)) { 560 mPendingConfiguration = config; 561 } 562 } 563 } 564 565 public final void schedulePauseActivity(IBinder token, boolean finished, 566 boolean userLeaving, int configChanges) { 567 queueOrSendMessage( 568 finished ? H.PAUSE_ACTIVITY_FINISHING : H.PAUSE_ACTIVITY, 569 token, 570 (userLeaving ? 1 : 0), 571 configChanges); 572 } 573 574 public final void scheduleStopActivity(IBinder token, boolean showWindow, 575 int configChanges) { 576 queueOrSendMessage( 577 showWindow ? H.STOP_ACTIVITY_SHOW : H.STOP_ACTIVITY_HIDE, 578 token, 0, configChanges); 579 } 580 581 public final void scheduleWindowVisibility(IBinder token, boolean showWindow) { 582 queueOrSendMessage( 583 showWindow ? H.SHOW_WINDOW : H.HIDE_WINDOW, 584 token); 585 } 586 587 public final void scheduleSleeping(IBinder token, boolean sleeping) { 588 queueOrSendMessage(H.SLEEPING, token, sleeping ? 1 : 0); 589 } 590 591 public final void scheduleResumeActivity(IBinder token, boolean isForward) { 592 queueOrSendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0); 593 } 594 595 public final void scheduleSendResult(IBinder token, List<ResultInfo> results) { 596 ResultData res = new ResultData(); 597 res.token = token; 598 res.results = results; 599 queueOrSendMessage(H.SEND_RESULT, res); 600 } 601 602 // we use token to identify this activity without having to send the 603 // activity itself back to the activity manager. (matters more with ipc) 604 public final void scheduleLaunchActivity(Intent intent, IBinder token, int ident, 605 ActivityInfo info, Configuration curConfig, CompatibilityInfo compatInfo, 606 Bundle state, List<ResultInfo> pendingResults, 607 List<Intent> pendingNewIntents, boolean notResumed, boolean isForward, 608 String profileName, ParcelFileDescriptor profileFd, boolean autoStopProfiler) { 609 ActivityClientRecord r = new ActivityClientRecord(); 610 611 r.token = token; 612 r.ident = ident; 613 r.intent = intent; 614 r.activityInfo = info; 615 r.compatInfo = compatInfo; 616 r.state = state; 617 618 r.pendingResults = pendingResults; 619 r.pendingIntents = pendingNewIntents; 620 621 r.startsNotResumed = notResumed; 622 r.isForward = isForward; 623 624 r.profileFile = profileName; 625 r.profileFd = profileFd; 626 r.autoStopProfiler = autoStopProfiler; 627 628 updatePendingConfiguration(curConfig); 629 630 queueOrSendMessage(H.LAUNCH_ACTIVITY, r); 631 } 632 633 public final void scheduleRelaunchActivity(IBinder token, 634 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 635 int configChanges, boolean notResumed, Configuration config) { 636 requestRelaunchActivity(token, pendingResults, pendingNewIntents, 637 configChanges, notResumed, config, true); 638 } 639 640 public final void scheduleNewIntent(List<Intent> intents, IBinder token) { 641 NewIntentData data = new NewIntentData(); 642 data.intents = intents; 643 data.token = token; 644 645 queueOrSendMessage(H.NEW_INTENT, data); 646 } 647 648 public final void scheduleDestroyActivity(IBinder token, boolean finishing, 649 int configChanges) { 650 queueOrSendMessage(H.DESTROY_ACTIVITY, token, finishing ? 1 : 0, 651 configChanges); 652 } 653 654 public final void scheduleReceiver(Intent intent, ActivityInfo info, 655 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras, 656 boolean sync, int sendingUser) { 657 ReceiverData r = new ReceiverData(intent, resultCode, data, extras, 658 sync, false, mAppThread.asBinder(), sendingUser); 659 r.info = info; 660 r.compatInfo = compatInfo; 661 queueOrSendMessage(H.RECEIVER, r); 662 } 663 664 public final void scheduleCreateBackupAgent(ApplicationInfo app, 665 CompatibilityInfo compatInfo, int backupMode) { 666 CreateBackupAgentData d = new CreateBackupAgentData(); 667 d.appInfo = app; 668 d.compatInfo = compatInfo; 669 d.backupMode = backupMode; 670 671 queueOrSendMessage(H.CREATE_BACKUP_AGENT, d); 672 } 673 674 public final void scheduleDestroyBackupAgent(ApplicationInfo app, 675 CompatibilityInfo compatInfo) { 676 CreateBackupAgentData d = new CreateBackupAgentData(); 677 d.appInfo = app; 678 d.compatInfo = compatInfo; 679 680 queueOrSendMessage(H.DESTROY_BACKUP_AGENT, d); 681 } 682 683 public final void scheduleCreateService(IBinder token, 684 ServiceInfo info, CompatibilityInfo compatInfo) { 685 CreateServiceData s = new CreateServiceData(); 686 s.token = token; 687 s.info = info; 688 s.compatInfo = compatInfo; 689 690 queueOrSendMessage(H.CREATE_SERVICE, s); 691 } 692 693 public final void scheduleBindService(IBinder token, Intent intent, 694 boolean rebind) { 695 BindServiceData s = new BindServiceData(); 696 s.token = token; 697 s.intent = intent; 698 s.rebind = rebind; 699 700 if (DEBUG_SERVICE) 701 Slog.v(TAG, "scheduleBindService token=" + token + " intent=" + intent + " uid=" 702 + Binder.getCallingUid() + " pid=" + Binder.getCallingPid()); 703 queueOrSendMessage(H.BIND_SERVICE, s); 704 } 705 706 public final void scheduleUnbindService(IBinder token, Intent intent) { 707 BindServiceData s = new BindServiceData(); 708 s.token = token; 709 s.intent = intent; 710 711 queueOrSendMessage(H.UNBIND_SERVICE, s); 712 } 713 714 public final void scheduleServiceArgs(IBinder token, boolean taskRemoved, int startId, 715 int flags ,Intent args) { 716 ServiceArgsData s = new ServiceArgsData(); 717 s.token = token; 718 s.taskRemoved = taskRemoved; 719 s.startId = startId; 720 s.flags = flags; 721 s.args = args; 722 723 queueOrSendMessage(H.SERVICE_ARGS, s); 724 } 725 726 public final void scheduleStopService(IBinder token) { 727 queueOrSendMessage(H.STOP_SERVICE, token); 728 } 729 730 public final void bindApplication(String processName, 731 ApplicationInfo appInfo, List<ProviderInfo> providers, 732 ComponentName instrumentationName, String profileFile, 733 ParcelFileDescriptor profileFd, boolean autoStopProfiler, 734 Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, 735 IUiAutomationConnection instrumentationUiConnection, int debugMode, 736 boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent, 737 Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services, 738 Bundle coreSettings) { 739 740 if (services != null) { 741 // Setup the service cache in the ServiceManager 742 ServiceManager.initServiceCache(services); 743 } 744 745 setCoreSettings(coreSettings); 746 747 AppBindData data = new AppBindData(); 748 data.processName = processName; 749 data.appInfo = appInfo; 750 data.providers = providers; 751 data.instrumentationName = instrumentationName; 752 data.instrumentationArgs = instrumentationArgs; 753 data.instrumentationWatcher = instrumentationWatcher; 754 data.instrumentationUiAutomationConnection = instrumentationUiConnection; 755 data.debugMode = debugMode; 756 data.enableOpenGlTrace = enableOpenGlTrace; 757 data.restrictedBackupMode = isRestrictedBackupMode; 758 data.persistent = persistent; 759 data.config = config; 760 data.compatInfo = compatInfo; 761 data.initProfileFile = profileFile; 762 data.initProfileFd = profileFd; 763 data.initAutoStopProfiler = false; 764 queueOrSendMessage(H.BIND_APPLICATION, data); 765 } 766 767 public final void scheduleExit() { 768 queueOrSendMessage(H.EXIT_APPLICATION, null); 769 } 770 771 public final void scheduleSuicide() { 772 queueOrSendMessage(H.SUICIDE, null); 773 } 774 775 public void requestThumbnail(IBinder token) { 776 queueOrSendMessage(H.REQUEST_THUMBNAIL, token); 777 } 778 779 public void scheduleConfigurationChanged(Configuration config) { 780 updatePendingConfiguration(config); 781 queueOrSendMessage(H.CONFIGURATION_CHANGED, config); 782 } 783 784 public void updateTimeZone() { 785 TimeZone.setDefault(null); 786 } 787 788 public void clearDnsCache() { 789 // a non-standard API to get this to libcore 790 InetAddress.clearDnsCache(); 791 } 792 793 public void setHttpProxy(String host, String port, String exclList) { 794 Proxy.setHttpProxySystemProperty(host, port, exclList); 795 } 796 797 public void processInBackground() { 798 mH.removeMessages(H.GC_WHEN_IDLE); 799 mH.sendMessage(mH.obtainMessage(H.GC_WHEN_IDLE)); 800 } 801 802 public void dumpService(FileDescriptor fd, IBinder servicetoken, String[] args) { 803 DumpComponentInfo data = new DumpComponentInfo(); 804 try { 805 data.fd = ParcelFileDescriptor.dup(fd); 806 data.token = servicetoken; 807 data.args = args; 808 queueOrSendMessage(H.DUMP_SERVICE, data); 809 } catch (IOException e) { 810 Slog.w(TAG, "dumpService failed", e); 811 } 812 } 813 814 // This function exists to make sure all receiver dispatching is 815 // correctly ordered, since these are one-way calls and the binder driver 816 // applies transaction ordering per object for such calls. 817 public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, 818 int resultCode, String dataStr, Bundle extras, boolean ordered, 819 boolean sticky, int sendingUser) throws RemoteException { 820 receiver.performReceive(intent, resultCode, dataStr, extras, ordered, 821 sticky, sendingUser); 822 } 823 824 public void scheduleLowMemory() { 825 queueOrSendMessage(H.LOW_MEMORY, null); 826 } 827 828 public void scheduleActivityConfigurationChanged(IBinder token) { 829 queueOrSendMessage(H.ACTIVITY_CONFIGURATION_CHANGED, token); 830 } 831 832 public void profilerControl(boolean start, String path, ParcelFileDescriptor fd, 833 int profileType) { 834 ProfilerControlData pcd = new ProfilerControlData(); 835 pcd.path = path; 836 pcd.fd = fd; 837 queueOrSendMessage(H.PROFILER_CONTROL, pcd, start ? 1 : 0, profileType); 838 } 839 840 public void dumpHeap(boolean managed, String path, ParcelFileDescriptor fd) { 841 DumpHeapData dhd = new DumpHeapData(); 842 dhd.path = path; 843 dhd.fd = fd; 844 queueOrSendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0); 845 } 846 847 public void setSchedulingGroup(int group) { 848 // Note: do this immediately, since going into the foreground 849 // should happen regardless of what pending work we have to do 850 // and the activity manager will wait for us to report back that 851 // we are done before sending us to the background. 852 try { 853 Process.setProcessGroup(Process.myPid(), group); 854 } catch (Exception e) { 855 Slog.w(TAG, "Failed setting process group to " + group, e); 856 } 857 } 858 859 public void getMemoryInfo(Debug.MemoryInfo outInfo) { 860 Debug.getMemoryInfo(outInfo); 861 } 862 863 public void dispatchPackageBroadcast(int cmd, String[] packages) { 864 queueOrSendMessage(H.DISPATCH_PACKAGE_BROADCAST, packages, cmd); 865 } 866 867 public void scheduleCrash(String msg) { 868 queueOrSendMessage(H.SCHEDULE_CRASH, msg); 869 } 870 871 public void dumpActivity(FileDescriptor fd, IBinder activitytoken, 872 String prefix, String[] args) { 873 DumpComponentInfo data = new DumpComponentInfo(); 874 try { 875 data.fd = ParcelFileDescriptor.dup(fd); 876 data.token = activitytoken; 877 data.prefix = prefix; 878 data.args = args; 879 queueOrSendMessage(H.DUMP_ACTIVITY, data); 880 } catch (IOException e) { 881 Slog.w(TAG, "dumpActivity failed", e); 882 } 883 } 884 885 public void dumpProvider(FileDescriptor fd, IBinder providertoken, 886 String[] args) { 887 DumpComponentInfo data = new DumpComponentInfo(); 888 try { 889 data.fd = ParcelFileDescriptor.dup(fd); 890 data.token = providertoken; 891 data.args = args; 892 queueOrSendMessage(H.DUMP_PROVIDER, data); 893 } catch (IOException e) { 894 Slog.w(TAG, "dumpProvider failed", e); 895 } 896 } 897 898 @Override 899 public Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, boolean checkin, 900 boolean dumpInfo, boolean dumpDalvik, String[] args) { 901 FileOutputStream fout = new FileOutputStream(fd); 902 PrintWriter pw = new PrintWriter(fout); 903 try { 904 return dumpMemInfo(pw, checkin, dumpInfo, dumpDalvik); 905 } finally { 906 pw.flush(); 907 } 908 } 909 910 private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, boolean checkin, boolean dumpInfo, 911 boolean dumpDalvik) { 912 long nativeMax = Debug.getNativeHeapSize() / 1024; 913 long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024; 914 long nativeFree = Debug.getNativeHeapFreeSize() / 1024; 915 916 Debug.MemoryInfo memInfo = new Debug.MemoryInfo(); 917 Debug.getMemoryInfo(memInfo); 918 919 if (!dumpInfo) { 920 return memInfo; 921 } 922 923 Runtime runtime = Runtime.getRuntime(); 924 925 long dalvikMax = runtime.totalMemory() / 1024; 926 long dalvikFree = runtime.freeMemory() / 1024; 927 long dalvikAllocated = dalvikMax - dalvikFree; 928 long viewInstanceCount = ViewDebug.getViewInstanceCount(); 929 long viewRootInstanceCount = ViewDebug.getViewRootImplCount(); 930 long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class); 931 long activityInstanceCount = Debug.countInstancesOfClass(Activity.class); 932 int globalAssetCount = AssetManager.getGlobalAssetCount(); 933 int globalAssetManagerCount = AssetManager.getGlobalAssetManagerCount(); 934 int binderLocalObjectCount = Debug.getBinderLocalObjectCount(); 935 int binderProxyObjectCount = Debug.getBinderProxyObjectCount(); 936 int binderDeathObjectCount = Debug.getBinderDeathObjectCount(); 937 long openSslSocketCount = Debug.countInstancesOfClass(OpenSSLSocketImpl.class); 938 SQLiteDebug.PagerStats stats = SQLiteDebug.getDatabaseInfo(); 939 940 // For checkin, we print one long comma-separated list of values 941 if (checkin) { 942 // NOTE: if you change anything significant below, also consider changing 943 // ACTIVITY_THREAD_CHECKIN_VERSION. 944 String processName = (mBoundApplication != null) 945 ? mBoundApplication.processName : "unknown"; 946 947 // Header 948 pw.print(ACTIVITY_THREAD_CHECKIN_VERSION); pw.print(','); 949 pw.print(Process.myPid()); pw.print(','); 950 pw.print(processName); pw.print(','); 951 952 // Heap info - max 953 pw.print(nativeMax); pw.print(','); 954 pw.print(dalvikMax); pw.print(','); 955 pw.print("N/A,"); 956 pw.print(nativeMax + dalvikMax); pw.print(','); 957 958 // Heap info - allocated 959 pw.print(nativeAllocated); pw.print(','); 960 pw.print(dalvikAllocated); pw.print(','); 961 pw.print("N/A,"); 962 pw.print(nativeAllocated + dalvikAllocated); pw.print(','); 963 964 // Heap info - free 965 pw.print(nativeFree); pw.print(','); 966 pw.print(dalvikFree); pw.print(','); 967 pw.print("N/A,"); 968 pw.print(nativeFree + dalvikFree); pw.print(','); 969 970 // Heap info - proportional set size 971 pw.print(memInfo.nativePss); pw.print(','); 972 pw.print(memInfo.dalvikPss); pw.print(','); 973 pw.print(memInfo.otherPss); pw.print(','); 974 pw.print(memInfo.nativePss + memInfo.dalvikPss + memInfo.otherPss); pw.print(','); 975 976 // Heap info - proportional set size 977 pw.print(memInfo.nativeSwappablePss); pw.print(','); 978 pw.print(memInfo.dalvikSwappablePss); pw.print(','); 979 pw.print(memInfo.otherSwappablePss); pw.print(','); 980 pw.print(memInfo.nativeSwappablePss + memInfo.dalvikSwappablePss + memInfo.otherSwappablePss); pw.print(','); 981 982 // Heap info - shared dirty 983 pw.print(memInfo.nativeSharedDirty); pw.print(','); 984 pw.print(memInfo.dalvikSharedDirty); pw.print(','); 985 pw.print(memInfo.otherSharedDirty); pw.print(','); 986 pw.print(memInfo.nativeSharedDirty + memInfo.dalvikSharedDirty 987 + memInfo.otherSharedDirty); pw.print(','); 988 989 // Heap info - shared clean 990 pw.print(memInfo.nativeSharedClean); pw.print(','); 991 pw.print(memInfo.dalvikSharedClean); pw.print(','); 992 pw.print(memInfo.otherSharedClean); pw.print(','); 993 pw.print(memInfo.nativeSharedClean + memInfo.dalvikSharedClean 994 + memInfo.otherSharedClean); pw.print(','); 995 996 // Heap info - private Dirty 997 pw.print(memInfo.nativePrivateDirty); pw.print(','); 998 pw.print(memInfo.dalvikPrivateDirty); pw.print(','); 999 pw.print(memInfo.otherPrivateDirty); pw.print(','); 1000 pw.print(memInfo.nativePrivateDirty + memInfo.dalvikPrivateDirty 1001 + memInfo.otherPrivateDirty); pw.print(','); 1002 1003 1004 // Heap info - private Clean 1005 pw.print(memInfo.nativePrivateClean); pw.print(','); 1006 pw.print(memInfo.dalvikPrivateClean); pw.print(','); 1007 pw.print(memInfo.otherPrivateClean); pw.print(','); 1008 pw.print(memInfo.nativePrivateClean + memInfo.dalvikPrivateClean 1009 + memInfo.otherPrivateClean); pw.print(','); 1010 1011 1012 // Object counts 1013 pw.print(viewInstanceCount); pw.print(','); 1014 pw.print(viewRootInstanceCount); pw.print(','); 1015 pw.print(appContextInstanceCount); pw.print(','); 1016 pw.print(activityInstanceCount); pw.print(','); 1017 1018 pw.print(globalAssetCount); pw.print(','); 1019 pw.print(globalAssetManagerCount); pw.print(','); 1020 pw.print(binderLocalObjectCount); pw.print(','); 1021 pw.print(binderProxyObjectCount); pw.print(','); 1022 1023 pw.print(binderDeathObjectCount); pw.print(','); 1024 pw.print(openSslSocketCount); pw.print(','); 1025 1026 // SQL 1027 pw.print(stats.memoryUsed / 1024); pw.print(','); 1028 pw.print(stats.memoryUsed / 1024); pw.print(','); 1029 pw.print(stats.pageCacheOverflow / 1024); pw.print(','); 1030 pw.print(stats.largestMemAlloc / 1024); 1031 for (int i = 0; i < stats.dbStats.size(); i++) { 1032 DbStats dbStats = stats.dbStats.get(i); 1033 pw.print(','); pw.print(dbStats.dbName); 1034 pw.print(','); pw.print(dbStats.pageSize); 1035 pw.print(','); pw.print(dbStats.dbSize); 1036 pw.print(','); pw.print(dbStats.lookaside); 1037 pw.print(','); pw.print(dbStats.cache); 1038 pw.print(','); pw.print(dbStats.cache); 1039 } 1040 pw.println(); 1041 1042 return memInfo; 1043 } 1044 1045 // otherwise, show human-readable format 1046 printRow(pw, HEAP_COLUMN, "", "Pss", "Pss","Shared", "Private", "Shared", "Private", 1047 "Heap", "Heap", "Heap"); 1048 printRow(pw, HEAP_COLUMN, "", "Total", "Clean", "Dirty", "Dirty", "Clean", "Clean", 1049 "Size", "Alloc", "Free"); 1050 printRow(pw, HEAP_COLUMN, "", "------", "------", "------", "------", "------", 1051 "------", "------", "------", "------"); 1052 printRow(pw, HEAP_COLUMN, "Native Heap", memInfo.nativePss, memInfo.nativeSwappablePss, 1053 memInfo.nativeSharedDirty, 1054 memInfo.nativePrivateDirty, memInfo.nativeSharedClean, 1055 memInfo.nativePrivateClean, nativeMax, nativeAllocated, nativeFree); 1056 printRow(pw, HEAP_COLUMN, "Dalvik Heap", memInfo.dalvikPss, memInfo.dalvikSwappablePss, 1057 memInfo.dalvikSharedDirty, 1058 memInfo.dalvikPrivateDirty, memInfo.dalvikSharedClean, 1059 memInfo.dalvikPrivateClean, dalvikMax, dalvikAllocated, dalvikFree); 1060 1061 int otherPss = memInfo.otherPss; 1062 int otherSwappablePss = memInfo.otherSwappablePss; 1063 int otherSharedDirty = memInfo.otherSharedDirty; 1064 int otherPrivateDirty = memInfo.otherPrivateDirty; 1065 int otherSharedClean = memInfo.otherSharedClean; 1066 int otherPrivateClean = memInfo.otherPrivateClean; 1067 1068 for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) { 1069 final int myPss = memInfo.getOtherPss(i); 1070 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 1071 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 1072 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 1073 final int mySharedClean = memInfo.getOtherSharedClean(i); 1074 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 1075 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 1076 || mySharedClean != 0 || myPrivateClean != 0) { 1077 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 1078 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 1079 mySharedClean, myPrivateClean, "", "", ""); 1080 otherPss -= myPss; 1081 otherSwappablePss -= mySwappablePss; 1082 otherSharedDirty -= mySharedDirty; 1083 otherPrivateDirty -= myPrivateDirty; 1084 otherSharedClean -= mySharedClean; 1085 otherPrivateClean -= myPrivateClean; 1086 } 1087 } 1088 1089 1090 1091 printRow(pw, HEAP_COLUMN, "Unknown", otherPss, otherSwappablePss, otherSharedDirty, 1092 otherPrivateDirty, otherSharedClean, otherPrivateClean,"", "", ""); 1093 printRow(pw, HEAP_COLUMN, "TOTAL", memInfo.getTotalPss(), 1094 memInfo.getTotalSwappablePss(), 1095 memInfo.getTotalSharedDirty(), memInfo.getTotalPrivateDirty(), 1096 memInfo.getTotalSharedClean(), memInfo.getTotalPrivateClean(), 1097 nativeMax+dalvikMax, 1098 nativeAllocated+dalvikAllocated, nativeFree+dalvikFree); 1099 1100 if (dumpDalvik) { 1101 pw.println(" "); 1102 pw.println(" Dalvik Details"); 1103 1104 for (int i=Debug.MemoryInfo.NUM_OTHER_STATS; 1105 i<Debug.MemoryInfo.NUM_OTHER_STATS + Debug.MemoryInfo.NUM_DVK_STATS; i++) { 1106 final int myPss = memInfo.getOtherPss(i); 1107 final int mySwappablePss = memInfo.getOtherSwappablePss(i); 1108 final int mySharedDirty = memInfo.getOtherSharedDirty(i); 1109 final int myPrivateDirty = memInfo.getOtherPrivateDirty(i); 1110 final int mySharedClean = memInfo.getOtherSharedClean(i); 1111 final int myPrivateClean = memInfo.getOtherPrivateClean(i); 1112 if (myPss != 0 || mySharedDirty != 0 || myPrivateDirty != 0 1113 || mySharedClean != 0 || myPrivateClean != 0) { 1114 printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i), 1115 myPss, mySwappablePss, mySharedDirty, myPrivateDirty, 1116 mySharedClean, myPrivateClean, "", "", ""); 1117 } 1118 } 1119 } 1120 1121 pw.println(" "); 1122 pw.println(" Objects"); 1123 printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:", 1124 viewRootInstanceCount); 1125 1126 printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount, 1127 "Activities:", activityInstanceCount); 1128 1129 printRow(pw, TWO_COUNT_COLUMNS, "Assets:", globalAssetCount, 1130 "AssetManagers:", globalAssetManagerCount); 1131 1132 printRow(pw, TWO_COUNT_COLUMNS, "Local Binders:", binderLocalObjectCount, 1133 "Proxy Binders:", binderProxyObjectCount); 1134 printRow(pw, ONE_COUNT_COLUMN, "Death Recipients:", binderDeathObjectCount); 1135 1136 printRow(pw, ONE_COUNT_COLUMN, "OpenSSL Sockets:", openSslSocketCount); 1137 1138 // SQLite mem info 1139 pw.println(" "); 1140 pw.println(" SQL"); 1141 printRow(pw, ONE_COUNT_COLUMN, "MEMORY_USED:", stats.memoryUsed / 1024); 1142 printRow(pw, TWO_COUNT_COLUMNS, "PAGECACHE_OVERFLOW:", 1143 stats.pageCacheOverflow / 1024, "MALLOC_SIZE:", stats.largestMemAlloc / 1024); 1144 pw.println(" "); 1145 int N = stats.dbStats.size(); 1146 if (N > 0) { 1147 pw.println(" DATABASES"); 1148 printRow(pw, " %8s %8s %14s %14s %s", "pgsz", "dbsz", "Lookaside(b)", "cache", 1149 "Dbname"); 1150 for (int i = 0; i < N; i++) { 1151 DbStats dbStats = stats.dbStats.get(i); 1152 printRow(pw, DB_INFO_FORMAT, 1153 (dbStats.pageSize > 0) ? String.valueOf(dbStats.pageSize) : " ", 1154 (dbStats.dbSize > 0) ? String.valueOf(dbStats.dbSize) : " ", 1155 (dbStats.lookaside > 0) ? String.valueOf(dbStats.lookaside) : " ", 1156 dbStats.cache, dbStats.dbName); 1157 } 1158 } 1159 1160 // Asset details. 1161 String assetAlloc = AssetManager.getAssetAllocations(); 1162 if (assetAlloc != null) { 1163 pw.println(" "); 1164 pw.println(" Asset Allocations"); 1165 pw.print(assetAlloc); 1166 } 1167 1168 return memInfo; 1169 } 1170 1171 @Override 1172 public void dumpGfxInfo(FileDescriptor fd, String[] args) { 1173 dumpGraphicsInfo(fd); 1174 WindowManagerGlobal.getInstance().dumpGfxInfo(fd); 1175 } 1176 1177 @Override 1178 public void dumpDbInfo(FileDescriptor fd, String[] args) { 1179 PrintWriter pw = new PrintWriter(new FileOutputStream(fd)); 1180 PrintWriterPrinter printer = new PrintWriterPrinter(pw); 1181 SQLiteDebug.dump(printer, args); 1182 pw.flush(); 1183 } 1184 1185 @Override 1186 public void unstableProviderDied(IBinder provider) { 1187 queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider); 1188 } 1189 1190 @Override 1191 public void requestActivityExtras(IBinder activityToken, IBinder requestToken, 1192 int requestType) { 1193 RequestActivityExtras cmd = new RequestActivityExtras(); 1194 cmd.activityToken = activityToken; 1195 cmd.requestToken = requestToken; 1196 cmd.requestType = requestType; 1197 queueOrSendMessage(H.REQUEST_ACTIVITY_EXTRAS, cmd); 1198 } 1199 1200 private void printRow(PrintWriter pw, String format, Object...objs) { 1201 pw.println(String.format(format, objs)); 1202 } 1203 1204 public void setCoreSettings(Bundle coreSettings) { 1205 queueOrSendMessage(H.SET_CORE_SETTINGS, coreSettings); 1206 } 1207 1208 public void updatePackageCompatibilityInfo(String pkg, CompatibilityInfo info) { 1209 UpdateCompatibilityData ucd = new UpdateCompatibilityData(); 1210 ucd.pkg = pkg; 1211 ucd.info = info; 1212 queueOrSendMessage(H.UPDATE_PACKAGE_COMPATIBILITY_INFO, ucd); 1213 } 1214 1215 public void scheduleTrimMemory(int level) { 1216 queueOrSendMessage(H.TRIM_MEMORY, null, level); 1217 } 1218 1219 } 1220 1221 private class H extends Handler { 1222 public static final int LAUNCH_ACTIVITY = 100; 1223 public static final int PAUSE_ACTIVITY = 101; 1224 public static final int PAUSE_ACTIVITY_FINISHING= 102; 1225 public static final int STOP_ACTIVITY_SHOW = 103; 1226 public static final int STOP_ACTIVITY_HIDE = 104; 1227 public static final int SHOW_WINDOW = 105; 1228 public static final int HIDE_WINDOW = 106; 1229 public static final int RESUME_ACTIVITY = 107; 1230 public static final int SEND_RESULT = 108; 1231 public static final int DESTROY_ACTIVITY = 109; 1232 public static final int BIND_APPLICATION = 110; 1233 public static final int EXIT_APPLICATION = 111; 1234 public static final int NEW_INTENT = 112; 1235 public static final int RECEIVER = 113; 1236 public static final int CREATE_SERVICE = 114; 1237 public static final int SERVICE_ARGS = 115; 1238 public static final int STOP_SERVICE = 116; 1239 public static final int REQUEST_THUMBNAIL = 117; 1240 public static final int CONFIGURATION_CHANGED = 118; 1241 public static final int CLEAN_UP_CONTEXT = 119; 1242 public static final int GC_WHEN_IDLE = 120; 1243 public static final int BIND_SERVICE = 121; 1244 public static final int UNBIND_SERVICE = 122; 1245 public static final int DUMP_SERVICE = 123; 1246 public static final int LOW_MEMORY = 124; 1247 public static final int ACTIVITY_CONFIGURATION_CHANGED = 125; 1248 public static final int RELAUNCH_ACTIVITY = 126; 1249 public static final int PROFILER_CONTROL = 127; 1250 public static final int CREATE_BACKUP_AGENT = 128; 1251 public static final int DESTROY_BACKUP_AGENT = 129; 1252 public static final int SUICIDE = 130; 1253 public static final int REMOVE_PROVIDER = 131; 1254 public static final int ENABLE_JIT = 132; 1255 public static final int DISPATCH_PACKAGE_BROADCAST = 133; 1256 public static final int SCHEDULE_CRASH = 134; 1257 public static final int DUMP_HEAP = 135; 1258 public static final int DUMP_ACTIVITY = 136; 1259 public static final int SLEEPING = 137; 1260 public static final int SET_CORE_SETTINGS = 138; 1261 public static final int UPDATE_PACKAGE_COMPATIBILITY_INFO = 139; 1262 public static final int TRIM_MEMORY = 140; 1263 public static final int DUMP_PROVIDER = 141; 1264 public static final int UNSTABLE_PROVIDER_DIED = 142; 1265 public static final int REQUEST_ACTIVITY_EXTRAS = 143; 1266 String codeToString(int code) { 1267 if (DEBUG_MESSAGES) { 1268 switch (code) { 1269 case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY"; 1270 case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY"; 1271 case PAUSE_ACTIVITY_FINISHING: return "PAUSE_ACTIVITY_FINISHING"; 1272 case STOP_ACTIVITY_SHOW: return "STOP_ACTIVITY_SHOW"; 1273 case STOP_ACTIVITY_HIDE: return "STOP_ACTIVITY_HIDE"; 1274 case SHOW_WINDOW: return "SHOW_WINDOW"; 1275 case HIDE_WINDOW: return "HIDE_WINDOW"; 1276 case RESUME_ACTIVITY: return "RESUME_ACTIVITY"; 1277 case SEND_RESULT: return "SEND_RESULT"; 1278 case DESTROY_ACTIVITY: return "DESTROY_ACTIVITY"; 1279 case BIND_APPLICATION: return "BIND_APPLICATION"; 1280 case EXIT_APPLICATION: return "EXIT_APPLICATION"; 1281 case NEW_INTENT: return "NEW_INTENT"; 1282 case RECEIVER: return "RECEIVER"; 1283 case CREATE_SERVICE: return "CREATE_SERVICE"; 1284 case SERVICE_ARGS: return "SERVICE_ARGS"; 1285 case STOP_SERVICE: return "STOP_SERVICE"; 1286 case REQUEST_THUMBNAIL: return "REQUEST_THUMBNAIL"; 1287 case CONFIGURATION_CHANGED: return "CONFIGURATION_CHANGED"; 1288 case CLEAN_UP_CONTEXT: return "CLEAN_UP_CONTEXT"; 1289 case GC_WHEN_IDLE: return "GC_WHEN_IDLE"; 1290 case BIND_SERVICE: return "BIND_SERVICE"; 1291 case UNBIND_SERVICE: return "UNBIND_SERVICE"; 1292 case DUMP_SERVICE: return "DUMP_SERVICE"; 1293 case LOW_MEMORY: return "LOW_MEMORY"; 1294 case ACTIVITY_CONFIGURATION_CHANGED: return "ACTIVITY_CONFIGURATION_CHANGED"; 1295 case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; 1296 case PROFILER_CONTROL: return "PROFILER_CONTROL"; 1297 case CREATE_BACKUP_AGENT: return "CREATE_BACKUP_AGENT"; 1298 case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT"; 1299 case SUICIDE: return "SUICIDE"; 1300 case REMOVE_PROVIDER: return "REMOVE_PROVIDER"; 1301 case ENABLE_JIT: return "ENABLE_JIT"; 1302 case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST"; 1303 case SCHEDULE_CRASH: return "SCHEDULE_CRASH"; 1304 case DUMP_HEAP: return "DUMP_HEAP"; 1305 case DUMP_ACTIVITY: return "DUMP_ACTIVITY"; 1306 case SLEEPING: return "SLEEPING"; 1307 case SET_CORE_SETTINGS: return "SET_CORE_SETTINGS"; 1308 case UPDATE_PACKAGE_COMPATIBILITY_INFO: return "UPDATE_PACKAGE_COMPATIBILITY_INFO"; 1309 case TRIM_MEMORY: return "TRIM_MEMORY"; 1310 case DUMP_PROVIDER: return "DUMP_PROVIDER"; 1311 case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED"; 1312 case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS"; 1313 } 1314 } 1315 return Integer.toString(code); 1316 } 1317 public void handleMessage(Message msg) { 1318 if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what)); 1319 switch (msg.what) { 1320 case LAUNCH_ACTIVITY: { 1321 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); 1322 ActivityClientRecord r = (ActivityClientRecord)msg.obj; 1323 1324 r.packageInfo = getPackageInfoNoCheck( 1325 r.activityInfo.applicationInfo, r.compatInfo); 1326 handleLaunchActivity(r, null); 1327 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1328 } break; 1329 case RELAUNCH_ACTIVITY: { 1330 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); 1331 ActivityClientRecord r = (ActivityClientRecord)msg.obj; 1332 handleRelaunchActivity(r); 1333 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1334 } break; 1335 case PAUSE_ACTIVITY: 1336 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 1337 handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2); 1338 maybeSnapshot(); 1339 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1340 break; 1341 case PAUSE_ACTIVITY_FINISHING: 1342 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); 1343 handlePauseActivity((IBinder)msg.obj, true, msg.arg1 != 0, msg.arg2); 1344 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1345 break; 1346 case STOP_ACTIVITY_SHOW: 1347 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 1348 handleStopActivity((IBinder)msg.obj, true, msg.arg2); 1349 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1350 break; 1351 case STOP_ACTIVITY_HIDE: 1352 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStop"); 1353 handleStopActivity((IBinder)msg.obj, false, msg.arg2); 1354 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1355 break; 1356 case SHOW_WINDOW: 1357 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityShowWindow"); 1358 handleWindowVisibility((IBinder)msg.obj, true); 1359 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1360 break; 1361 case HIDE_WINDOW: 1362 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityHideWindow"); 1363 handleWindowVisibility((IBinder)msg.obj, false); 1364 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1365 break; 1366 case RESUME_ACTIVITY: 1367 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume"); 1368 handleResumeActivity((IBinder)msg.obj, true, 1369 msg.arg1 != 0, true); 1370 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1371 break; 1372 case SEND_RESULT: 1373 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDeliverResult"); 1374 handleSendResult((ResultData)msg.obj); 1375 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1376 break; 1377 case DESTROY_ACTIVITY: 1378 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityDestroy"); 1379 handleDestroyActivity((IBinder)msg.obj, msg.arg1 != 0, 1380 msg.arg2, false); 1381 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1382 break; 1383 case BIND_APPLICATION: 1384 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication"); 1385 AppBindData data = (AppBindData)msg.obj; 1386 handleBindApplication(data); 1387 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1388 break; 1389 case EXIT_APPLICATION: 1390 if (mInitialApplication != null) { 1391 mInitialApplication.onTerminate(); 1392 } 1393 Looper.myLooper().quit(); 1394 break; 1395 case NEW_INTENT: 1396 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityNewIntent"); 1397 handleNewIntent((NewIntentData)msg.obj); 1398 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1399 break; 1400 case RECEIVER: 1401 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp"); 1402 handleReceiver((ReceiverData)msg.obj); 1403 maybeSnapshot(); 1404 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1405 break; 1406 case CREATE_SERVICE: 1407 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceCreate"); 1408 handleCreateService((CreateServiceData)msg.obj); 1409 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1410 break; 1411 case BIND_SERVICE: 1412 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceBind"); 1413 handleBindService((BindServiceData)msg.obj); 1414 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1415 break; 1416 case UNBIND_SERVICE: 1417 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind"); 1418 handleUnbindService((BindServiceData)msg.obj); 1419 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1420 break; 1421 case SERVICE_ARGS: 1422 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStart"); 1423 handleServiceArgs((ServiceArgsData)msg.obj); 1424 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1425 break; 1426 case STOP_SERVICE: 1427 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop"); 1428 handleStopService((IBinder)msg.obj); 1429 maybeSnapshot(); 1430 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1431 break; 1432 case REQUEST_THUMBNAIL: 1433 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "requestThumbnail"); 1434 handleRequestThumbnail((IBinder)msg.obj); 1435 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1436 break; 1437 case CONFIGURATION_CHANGED: 1438 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "configChanged"); 1439 mCurDefaultDisplayDpi = ((Configuration)msg.obj).densityDpi; 1440 handleConfigurationChanged((Configuration)msg.obj, null); 1441 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1442 break; 1443 case CLEAN_UP_CONTEXT: 1444 ContextCleanupInfo cci = (ContextCleanupInfo)msg.obj; 1445 cci.context.performFinalCleanup(cci.who, cci.what); 1446 break; 1447 case GC_WHEN_IDLE: 1448 scheduleGcIdler(); 1449 break; 1450 case DUMP_SERVICE: 1451 handleDumpService((DumpComponentInfo)msg.obj); 1452 break; 1453 case LOW_MEMORY: 1454 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "lowMemory"); 1455 handleLowMemory(); 1456 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1457 break; 1458 case ACTIVITY_CONFIGURATION_CHANGED: 1459 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityConfigChanged"); 1460 handleActivityConfigurationChanged((IBinder)msg.obj); 1461 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1462 break; 1463 case PROFILER_CONTROL: 1464 handleProfilerControl(msg.arg1 != 0, (ProfilerControlData)msg.obj, msg.arg2); 1465 break; 1466 case CREATE_BACKUP_AGENT: 1467 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupCreateAgent"); 1468 handleCreateBackupAgent((CreateBackupAgentData)msg.obj); 1469 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1470 break; 1471 case DESTROY_BACKUP_AGENT: 1472 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "backupDestroyAgent"); 1473 handleDestroyBackupAgent((CreateBackupAgentData)msg.obj); 1474 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1475 break; 1476 case SUICIDE: 1477 Process.killProcess(Process.myPid()); 1478 break; 1479 case REMOVE_PROVIDER: 1480 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "providerRemove"); 1481 completeRemoveProvider((ProviderRefCount)msg.obj); 1482 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1483 break; 1484 case ENABLE_JIT: 1485 ensureJitEnabled(); 1486 break; 1487 case DISPATCH_PACKAGE_BROADCAST: 1488 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage"); 1489 handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj); 1490 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1491 break; 1492 case SCHEDULE_CRASH: 1493 throw new RemoteServiceException((String)msg.obj); 1494 case DUMP_HEAP: 1495 handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj); 1496 break; 1497 case DUMP_ACTIVITY: 1498 handleDumpActivity((DumpComponentInfo)msg.obj); 1499 break; 1500 case DUMP_PROVIDER: 1501 handleDumpProvider((DumpComponentInfo)msg.obj); 1502 break; 1503 case SLEEPING: 1504 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "sleeping"); 1505 handleSleeping((IBinder)msg.obj, msg.arg1 != 0); 1506 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1507 break; 1508 case SET_CORE_SETTINGS: 1509 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setCoreSettings"); 1510 handleSetCoreSettings((Bundle) msg.obj); 1511 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1512 break; 1513 case UPDATE_PACKAGE_COMPATIBILITY_INFO: 1514 handleUpdatePackageCompatibilityInfo((UpdateCompatibilityData)msg.obj); 1515 break; 1516 case TRIM_MEMORY: 1517 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "trimMemory"); 1518 handleTrimMemory(msg.arg1); 1519 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1520 break; 1521 case UNSTABLE_PROVIDER_DIED: 1522 handleUnstableProviderDied((IBinder)msg.obj, false); 1523 break; 1524 case REQUEST_ACTIVITY_EXTRAS: 1525 handleRequestActivityExtras((RequestActivityExtras)msg.obj); 1526 break; 1527 } 1528 if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what)); 1529 } 1530 1531 private void maybeSnapshot() { 1532 if (mBoundApplication != null && SamplingProfilerIntegration.isEnabled()) { 1533 // convert the *private* ActivityThread.PackageInfo to *public* known 1534 // android.content.pm.PackageInfo 1535 String packageName = mBoundApplication.info.mPackageName; 1536 android.content.pm.PackageInfo packageInfo = null; 1537 try { 1538 Context context = getSystemContext(); 1539 if(context == null) { 1540 Log.e(TAG, "cannot get a valid context"); 1541 return; 1542 } 1543 PackageManager pm = context.getPackageManager(); 1544 if(pm == null) { 1545 Log.e(TAG, "cannot get a valid PackageManager"); 1546 return; 1547 } 1548 packageInfo = pm.getPackageInfo( 1549 packageName, PackageManager.GET_ACTIVITIES); 1550 } catch (NameNotFoundException e) { 1551 Log.e(TAG, "cannot get package info for " + packageName, e); 1552 } 1553 SamplingProfilerIntegration.writeSnapshot(mBoundApplication.processName, packageInfo); 1554 } 1555 } 1556 } 1557 1558 private class Idler implements MessageQueue.IdleHandler { 1559 @Override 1560 public final boolean queueIdle() { 1561 ActivityClientRecord a = mNewActivities; 1562 boolean stopProfiling = false; 1563 if (mBoundApplication != null && mProfiler.profileFd != null 1564 && mProfiler.autoStopProfiler) { 1565 stopProfiling = true; 1566 } 1567 if (a != null) { 1568 mNewActivities = null; 1569 IActivityManager am = ActivityManagerNative.getDefault(); 1570 ActivityClientRecord prev; 1571 do { 1572 if (localLOGV) Slog.v( 1573 TAG, "Reporting idle of " + a + 1574 " finished=" + 1575 (a.activity != null && a.activity.mFinished)); 1576 if (a.activity != null && !a.activity.mFinished) { 1577 try { 1578 am.activityIdle(a.token, a.createdConfig, stopProfiling); 1579 a.createdConfig = null; 1580 } catch (RemoteException ex) { 1581 // Ignore 1582 } 1583 } 1584 prev = a; 1585 a = a.nextIdle; 1586 prev.nextIdle = null; 1587 } while (a != null); 1588 } 1589 if (stopProfiling) { 1590 mProfiler.stopProfiling(); 1591 } 1592 ensureJitEnabled(); 1593 return false; 1594 } 1595 } 1596 1597 final class GcIdler implements MessageQueue.IdleHandler { 1598 @Override 1599 public final boolean queueIdle() { 1600 doGcIfNeeded(); 1601 return false; 1602 } 1603 } 1604 1605 private static class ResourcesKey { 1606 final private String mResDir; 1607 final private int mDisplayId; 1608 final private Configuration mOverrideConfiguration; 1609 final private float mScale; 1610 final private int mHash; 1611 final private IBinder mToken; 1612 1613 ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, 1614 float scale, IBinder token) { 1615 mResDir = resDir; 1616 mDisplayId = displayId; 1617 if (overrideConfiguration != null) { 1618 if (Configuration.EMPTY.equals(overrideConfiguration)) { 1619 overrideConfiguration = null; 1620 } 1621 } 1622 mOverrideConfiguration = overrideConfiguration; 1623 mScale = scale; 1624 int hash = 17; 1625 hash = 31 * hash + mResDir.hashCode(); 1626 hash = 31 * hash + mDisplayId; 1627 hash = 31 * hash + (mOverrideConfiguration != null 1628 ? mOverrideConfiguration.hashCode() : 0); 1629 hash = 31 * hash + Float.floatToIntBits(mScale); 1630 if (DEVELOPMENT_RESOURCES_DEPEND_ON_ACTIVITY_TOKEN) { 1631 mToken = token; 1632 hash = 31 * hash + (mToken == null ? 0 : mToken.hashCode()); 1633 } else { 1634 mToken = null; 1635 } 1636 mHash = hash; 1637 } 1638 1639 @Override 1640 public int hashCode() { 1641 return mHash; 1642 } 1643 1644 @Override 1645 public boolean equals(Object obj) { 1646 if (!(obj instanceof ResourcesKey)) { 1647 return false; 1648 } 1649 ResourcesKey peer = (ResourcesKey) obj; 1650 if (!mResDir.equals(peer.mResDir)) { 1651 return false; 1652 } 1653 if (mDisplayId != peer.mDisplayId) { 1654 return false; 1655 } 1656 if (mOverrideConfiguration != peer.mOverrideConfiguration) { 1657 if (mOverrideConfiguration == null || peer.mOverrideConfiguration == null) { 1658 return false; 1659 } 1660 if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) { 1661 return false; 1662 } 1663 } 1664 if (mScale != peer.mScale) { 1665 return false; 1666 } 1667 return true; 1668 } 1669 } 1670 1671 public static ActivityThread currentActivityThread() { 1672 return sCurrentActivityThread; 1673 } 1674 1675 public static String currentPackageName() { 1676 ActivityThread am = currentActivityThread(); 1677 return (am != null && am.mBoundApplication != null) 1678 ? am.mBoundApplication.appInfo.packageName : null; 1679 } 1680 1681 public static String currentProcessName() { 1682 ActivityThread am = currentActivityThread(); 1683 return (am != null && am.mBoundApplication != null) 1684 ? am.mBoundApplication.processName : null; 1685 } 1686 1687 public static Application currentApplication() { 1688 ActivityThread am = currentActivityThread(); 1689 return am != null ? am.mInitialApplication : null; 1690 } 1691 1692 public static IPackageManager getPackageManager() { 1693 if (sPackageManager != null) { 1694 //Slog.v("PackageManager", "returning cur default = " + sPackageManager); 1695 return sPackageManager; 1696 } 1697 IBinder b = ServiceManager.getService("package"); 1698 //Slog.v("PackageManager", "default service binder = " + b); 1699 sPackageManager = IPackageManager.Stub.asInterface(b); 1700 //Slog.v("PackageManager", "default service = " + sPackageManager); 1701 return sPackageManager; 1702 } 1703 1704 private void flushDisplayMetricsLocked() { 1705 mDefaultDisplayMetrics.clear(); 1706 } 1707 1708 DisplayMetrics getDisplayMetricsLocked(int displayId) { 1709 return getDisplayMetricsLocked(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); 1710 } 1711 1712 DisplayMetrics getDisplayMetricsLocked(int displayId, DisplayAdjustments daj) { 1713 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); 1714 DisplayMetrics dm = isDefaultDisplay ? mDefaultDisplayMetrics.get(daj) : null; 1715 if (dm != null) { 1716 return dm; 1717 } 1718 dm = new DisplayMetrics(); 1719 1720 DisplayManagerGlobal displayManager = DisplayManagerGlobal.getInstance(); 1721 if (displayManager == null) { 1722 // may be null early in system startup 1723 dm.setToDefaults(); 1724 return dm; 1725 } 1726 1727 if (isDefaultDisplay) { 1728 mDefaultDisplayMetrics.put(daj, dm); 1729 } 1730 1731 Display d = displayManager.getCompatibleDisplay(displayId, daj); 1732 if (d != null) { 1733 d.getMetrics(dm); 1734 } else { 1735 // Display no longer exists 1736 // FIXME: This would not be a problem if we kept the Display object around 1737 // instead of using the raw display id everywhere. The Display object caches 1738 // its information even after the display has been removed. 1739 dm.setToDefaults(); 1740 } 1741 //Slog.i("foo", "New metrics: w=" + metrics.widthPixels + " h=" 1742 // + metrics.heightPixels + " den=" + metrics.density 1743 // + " xdpi=" + metrics.xdpi + " ydpi=" + metrics.ydpi); 1744 return dm; 1745 } 1746 1747 private Configuration mMainThreadConfig = new Configuration(); 1748 Configuration applyConfigCompatMainThread(int displayDensity, Configuration config, 1749 CompatibilityInfo compat) { 1750 if (config == null) { 1751 return null; 1752 } 1753 if (!compat.supportsScreen()) { 1754 mMainThreadConfig.setTo(config); 1755 config = mMainThreadConfig; 1756 compat.applyToConfiguration(displayDensity, config); 1757 } 1758 return config; 1759 } 1760 1761 /** 1762 * Creates the top level Resources for applications with the given compatibility info. 1763 * 1764 * @param resDir the resource directory. 1765 * @param compatInfo the compability info. Must not be null. 1766 * @param token the application token for determining stack bounds. 1767 */ 1768 Resources getTopLevelResources(String resDir, int displayId, 1769 Configuration overrideConfiguration, CompatibilityInfo compatInfo, IBinder token) { 1770 final float scale = compatInfo.applicationScale; 1771 ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, scale, 1772 token); 1773 Resources r; 1774 synchronized (mPackages) { 1775 // Resources is app scale dependent. 1776 if (false) { 1777 Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale); 1778 } 1779 WeakReference<Resources> wr = mActiveResources.get(key); 1780 r = wr != null ? wr.get() : null; 1781 //if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate()); 1782 if (r != null && r.getAssets().isUpToDate()) { 1783 if (false) { 1784 Slog.w(TAG, "Returning cached resources " + r + " " + resDir 1785 + ": appScale=" + r.getCompatibilityInfo().applicationScale); 1786 } 1787 return r; 1788 } 1789 } 1790 1791 //if (r != null) { 1792 // Slog.w(TAG, "Throwing away out-of-date resources!!!! " 1793 // + r + " " + resDir); 1794 //} 1795 1796 AssetManager assets = new AssetManager(); 1797 if (assets.addAssetPath(resDir) == 0) { 1798 return null; 1799 } 1800 1801 //Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics); 1802 DisplayMetrics dm = getDisplayMetricsLocked(displayId); 1803 Configuration config; 1804 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); 1805 if (!isDefaultDisplay || key.mOverrideConfiguration != null) { 1806 config = new Configuration(getConfiguration()); 1807 if (!isDefaultDisplay) { 1808 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config); 1809 } 1810 if (key.mOverrideConfiguration != null) { 1811 config.updateFrom(key.mOverrideConfiguration); 1812 } 1813 } else { 1814 config = getConfiguration(); 1815 } 1816 r = new Resources(assets, dm, config, compatInfo, token); 1817 if (false) { 1818 Slog.i(TAG, "Created app resources " + resDir + " " + r + ": " 1819 + r.getConfiguration() + " appScale=" 1820 + r.getCompatibilityInfo().applicationScale); 1821 } 1822 1823 synchronized (mPackages) { 1824 WeakReference<Resources> wr = mActiveResources.get(key); 1825 Resources existing = wr != null ? wr.get() : null; 1826 if (existing != null && existing.getAssets().isUpToDate()) { 1827 // Someone else already created the resources while we were 1828 // unlocked; go ahead and use theirs. 1829 r.getAssets().close(); 1830 return existing; 1831 } 1832 1833 // XXX need to remove entries when weak references go away 1834 mActiveResources.put(key, new WeakReference<Resources>(r)); 1835 return r; 1836 } 1837 } 1838 1839 /** 1840 * Creates the top level resources for the given package. 1841 */ 1842 Resources getTopLevelResources(String resDir, 1843 int displayId, Configuration overrideConfiguration, 1844 LoadedApk pkgInfo) { 1845 return getTopLevelResources(resDir, displayId, overrideConfiguration, 1846 pkgInfo.getCompatibilityInfo(), null); 1847 } 1848 1849 final Handler getHandler() { 1850 return mH; 1851 } 1852 1853 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, 1854 int flags) { 1855 return getPackageInfo(packageName, compatInfo, flags, UserHandle.myUserId()); 1856 } 1857 1858 public final LoadedApk getPackageInfo(String packageName, CompatibilityInfo compatInfo, 1859 int flags, int userId) { 1860 synchronized (mPackages) { 1861 WeakReference<LoadedApk> ref; 1862 if ((flags&Context.CONTEXT_INCLUDE_CODE) != 0) { 1863 ref = mPackages.get(packageName); 1864 } else { 1865 ref = mResourcePackages.get(packageName); 1866 } 1867 LoadedApk packageInfo = ref != null ? ref.get() : null; 1868 //Slog.i(TAG, "getPackageInfo " + packageName + ": " + packageInfo); 1869 //if (packageInfo != null) Slog.i(TAG, "isUptoDate " + packageInfo.mResDir 1870 // + ": " + packageInfo.mResources.getAssets().isUpToDate()); 1871 if (packageInfo != null && (packageInfo.mResources == null 1872 || packageInfo.mResources.getAssets().isUpToDate())) { 1873 if (packageInfo.isSecurityViolation() 1874 && (flags&Context.CONTEXT_IGNORE_SECURITY) == 0) { 1875 throw new SecurityException( 1876 "Requesting code from " + packageName 1877 + " to be run in process " 1878 + mBoundApplication.processName 1879 + "/" + mBoundApplication.appInfo.uid); 1880 } 1881 return packageInfo; 1882 } 1883 } 1884 1885 ApplicationInfo ai = null; 1886 try { 1887 ai = getPackageManager().getApplicationInfo(packageName, 1888 PackageManager.GET_SHARED_LIBRARY_FILES, userId); 1889 } catch (RemoteException e) { 1890 // Ignore 1891 } 1892 1893 if (ai != null) { 1894 return getPackageInfo(ai, compatInfo, flags); 1895 } 1896 1897 return null; 1898 } 1899 1900 public final LoadedApk getPackageInfo(ApplicationInfo ai, CompatibilityInfo compatInfo, 1901 int flags) { 1902 boolean includeCode = (flags&Context.CONTEXT_INCLUDE_CODE) != 0; 1903 boolean securityViolation = includeCode && ai.uid != 0 1904 && ai.uid != Process.SYSTEM_UID && (mBoundApplication != null 1905 ? !UserHandle.isSameApp(ai.uid, mBoundApplication.appInfo.uid) 1906 : true); 1907 if ((flags&(Context.CONTEXT_INCLUDE_CODE 1908 |Context.CONTEXT_IGNORE_SECURITY)) 1909 == Context.CONTEXT_INCLUDE_CODE) { 1910 if (securityViolation) { 1911 String msg = "Requesting code from " + ai.packageName 1912 + " (with uid " + ai.uid + ")"; 1913 if (mBoundApplication != null) { 1914 msg = msg + " to be run in process " 1915 + mBoundApplication.processName + " (with uid " 1916 + mBoundApplication.appInfo.uid + ")"; 1917 } 1918 throw new SecurityException(msg); 1919 } 1920 } 1921 return getPackageInfo(ai, compatInfo, null, securityViolation, includeCode); 1922 } 1923 1924 public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, 1925 CompatibilityInfo compatInfo) { 1926 return getPackageInfo(ai, compatInfo, null, false, true); 1927 } 1928 1929 public final LoadedApk peekPackageInfo(String packageName, boolean includeCode) { 1930 synchronized (mPackages) { 1931 WeakReference<LoadedApk> ref; 1932 if (includeCode) { 1933 ref = mPackages.get(packageName); 1934 } else { 1935 ref = mResourcePackages.get(packageName); 1936 } 1937 return ref != null ? ref.get() : null; 1938 } 1939 } 1940 1941 private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo, 1942 ClassLoader baseLoader, boolean securityViolation, boolean includeCode) { 1943 synchronized (mPackages) { 1944 WeakReference<LoadedApk> ref; 1945 if (includeCode) { 1946 ref = mPackages.get(aInfo.packageName); 1947 } else { 1948 ref = mResourcePackages.get(aInfo.packageName); 1949 } 1950 LoadedApk packageInfo = ref != null ? ref.get() : null; 1951 if (packageInfo == null || (packageInfo.mResources != null 1952 && !packageInfo.mResources.getAssets().isUpToDate())) { 1953 if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package " 1954 : "Loading resource-only package ") + aInfo.packageName 1955 + " (in " + (mBoundApplication != null 1956 ? mBoundApplication.processName : null) 1957 + ")"); 1958 packageInfo = 1959 new LoadedApk(this, aInfo, compatInfo, this, baseLoader, 1960 securityViolation, includeCode && 1961 (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0); 1962 if (includeCode) { 1963 mPackages.put(aInfo.packageName, 1964 new WeakReference<LoadedApk>(packageInfo)); 1965 } else { 1966 mResourcePackages.put(aInfo.packageName, 1967 new WeakReference<LoadedApk>(packageInfo)); 1968 } 1969 } 1970 return packageInfo; 1971 } 1972 } 1973 1974 ActivityThread() { 1975 } 1976 1977 public ApplicationThread getApplicationThread() 1978 { 1979 return mAppThread; 1980 } 1981 1982 public Instrumentation getInstrumentation() 1983 { 1984 return mInstrumentation; 1985 } 1986 1987 public Configuration getConfiguration() { 1988 return mResConfiguration; 1989 } 1990 1991 public boolean isProfiling() { 1992 return mProfiler != null && mProfiler.profileFile != null 1993 && mProfiler.profileFd == null; 1994 } 1995 1996 public String getProfileFilePath() { 1997 return mProfiler.profileFile; 1998 } 1999 2000 public Looper getLooper() { 2001 return mLooper; 2002 } 2003 2004 public Application getApplication() { 2005 return mInitialApplication; 2006 } 2007 2008 public String getProcessName() { 2009 return mBoundApplication.processName; 2010 } 2011 2012 public ContextImpl getSystemContext() { 2013 synchronized (this) { 2014 if (mSystemContext == null) { 2015 ContextImpl context = 2016 ContextImpl.createSystemContext(this); 2017 LoadedApk info = new LoadedApk(this, "android", context, null, 2018 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO); 2019 context.init(info, null, this); 2020 context.getResources().updateConfiguration(getConfiguration(), 2021 getDisplayMetricsLocked(Display.DEFAULT_DISPLAY)); 2022 mSystemContext = context; 2023 //Slog.i(TAG, "Created system resources " + context.getResources() 2024 // + ": " + context.getResources().getConfiguration()); 2025 } 2026 } 2027 return mSystemContext; 2028 } 2029 2030 public void installSystemApplicationInfo(ApplicationInfo info) { 2031 synchronized (this) { 2032 ContextImpl context = getSystemContext(); 2033 context.init(new LoadedApk(this, "android", context, info, 2034 CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO), null, this); 2035 2036 // give ourselves a default profiler 2037 mProfiler = new Profiler(); 2038 } 2039 } 2040 2041 void ensureJitEnabled() { 2042 if (!mJitEnabled) { 2043 mJitEnabled = true; 2044 dalvik.system.VMRuntime.getRuntime().startJitCompilation(); 2045 } 2046 } 2047 2048 void scheduleGcIdler() { 2049 if (!mGcIdlerScheduled) { 2050 mGcIdlerScheduled = true; 2051 Looper.myQueue().addIdleHandler(mGcIdler); 2052 } 2053 mH.removeMessages(H.GC_WHEN_IDLE); 2054 } 2055 2056 void unscheduleGcIdler() { 2057 if (mGcIdlerScheduled) { 2058 mGcIdlerScheduled = false; 2059 Looper.myQueue().removeIdleHandler(mGcIdler); 2060 } 2061 mH.removeMessages(H.GC_WHEN_IDLE); 2062 } 2063 2064 void doGcIfNeeded() { 2065 mGcIdlerScheduled = false; 2066 final long now = SystemClock.uptimeMillis(); 2067 //Slog.i(TAG, "**** WE MIGHT WANT TO GC: then=" + Binder.getLastGcTime() 2068 // + "m now=" + now); 2069 if ((BinderInternal.getLastGcTime()+MIN_TIME_BETWEEN_GCS) < now) { 2070 //Slog.i(TAG, "**** WE DO, WE DO WANT TO GC!"); 2071 BinderInternal.forceGc("bg"); 2072 } 2073 } 2074 2075 public void registerOnActivityPausedListener(Activity activity, 2076 OnActivityPausedListener listener) { 2077 synchronized (mOnPauseListeners) { 2078 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity); 2079 if (list == null) { 2080 list = new ArrayList<OnActivityPausedListener>(); 2081 mOnPauseListeners.put(activity, list); 2082 } 2083 list.add(listener); 2084 } 2085 } 2086 2087 public void unregisterOnActivityPausedListener(Activity activity, 2088 OnActivityPausedListener listener) { 2089 synchronized (mOnPauseListeners) { 2090 ArrayList<OnActivityPausedListener> list = mOnPauseListeners.get(activity); 2091 if (list != null) { 2092 list.remove(listener); 2093 } 2094 } 2095 } 2096 2097 public final ActivityInfo resolveActivityInfo(Intent intent) { 2098 ActivityInfo aInfo = intent.resolveActivityInfo( 2099 mInitialApplication.getPackageManager(), PackageManager.GET_SHARED_LIBRARY_FILES); 2100 if (aInfo == null) { 2101 // Throw an exception. 2102 Instrumentation.checkStartActivityResult( 2103 ActivityManager.START_CLASS_NOT_FOUND, intent); 2104 } 2105 return aInfo; 2106 } 2107 2108 public final Activity startActivityNow(Activity parent, String id, 2109 Intent intent, ActivityInfo activityInfo, IBinder token, Bundle state, 2110 Activity.NonConfigurationInstances lastNonConfigurationInstances) { 2111 ActivityClientRecord r = new ActivityClientRecord(); 2112 r.token = token; 2113 r.ident = 0; 2114 r.intent = intent; 2115 r.state = state; 2116 r.parent = parent; 2117 r.embeddedID = id; 2118 r.activityInfo = activityInfo; 2119 r.lastNonConfigurationInstances = lastNonConfigurationInstances; 2120 if (localLOGV) { 2121 ComponentName compname = intent.getComponent(); 2122 String name; 2123 if (compname != null) { 2124 name = compname.toShortString(); 2125 } else { 2126 name = "(Intent " + intent + ").getComponent() returned null"; 2127 } 2128 Slog.v(TAG, "Performing launch: action=" + intent.getAction() 2129 + ", comp=" + name 2130 + ", token=" + token); 2131 } 2132 return performLaunchActivity(r, null); 2133 } 2134 2135 public final Activity getActivity(IBinder token) { 2136 return mActivities.get(token).activity; 2137 } 2138 2139 public final void sendActivityResult( 2140 IBinder token, String id, int requestCode, 2141 int resultCode, Intent data) { 2142 if (DEBUG_RESULTS) Slog.v(TAG, "sendActivityResult: id=" + id 2143 + " req=" + requestCode + " res=" + resultCode + " data=" + data); 2144 ArrayList<ResultInfo> list = new ArrayList<ResultInfo>(); 2145 list.add(new ResultInfo(id, requestCode, resultCode, data)); 2146 mAppThread.scheduleSendResult(token, list); 2147 } 2148 2149 // if the thread hasn't started yet, we don't have the handler, so just 2150 // save the messages until we're ready. 2151 private void queueOrSendMessage(int what, Object obj) { 2152 queueOrSendMessage(what, obj, 0, 0); 2153 } 2154 2155 private void queueOrSendMessage(int what, Object obj, int arg1) { 2156 queueOrSendMessage(what, obj, arg1, 0); 2157 } 2158 2159 private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) { 2160 synchronized (this) { 2161 if (DEBUG_MESSAGES) Slog.v( 2162 TAG, "SCHEDULE " + what + " " + mH.codeToString(what) 2163 + ": " + arg1 + " / " + obj); 2164 Message msg = Message.obtain(); 2165 msg.what = what; 2166 msg.obj = obj; 2167 msg.arg1 = arg1; 2168 msg.arg2 = arg2; 2169 mH.sendMessage(msg); 2170 } 2171 } 2172 2173 final void scheduleContextCleanup(ContextImpl context, String who, 2174 String what) { 2175 ContextCleanupInfo cci = new ContextCleanupInfo(); 2176 cci.context = context; 2177 cci.who = who; 2178 cci.what = what; 2179 queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci); 2180 } 2181 2182 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2183 // System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")"); 2184 2185 ActivityInfo aInfo = r.activityInfo; 2186 if (r.packageInfo == null) { 2187 r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo, 2188 Context.CONTEXT_INCLUDE_CODE); 2189 } 2190 2191 ComponentName component = r.intent.getComponent(); 2192 if (component == null) { 2193 component = r.intent.resolveActivity( 2194 mInitialApplication.getPackageManager()); 2195 r.intent.setComponent(component); 2196 } 2197 2198 if (r.activityInfo.targetActivity != null) { 2199 component = new ComponentName(r.activityInfo.packageName, 2200 r.activityInfo.targetActivity); 2201 } 2202 2203 Activity activity = null; 2204 try { 2205 java.lang.ClassLoader cl = r.packageInfo.getClassLoader(); 2206 activity = mInstrumentation.newActivity( 2207 cl, component.getClassName(), r.intent); 2208 StrictMode.incrementExpectedActivityCount(activity.getClass()); 2209 r.intent.setExtrasClassLoader(cl); 2210 if (r.state != null) { 2211 r.state.setClassLoader(cl); 2212 } 2213 } catch (Exception e) { 2214 if (!mInstrumentation.onException(activity, e)) { 2215 throw new RuntimeException( 2216 "Unable to instantiate activity " + component 2217 + ": " + e.toString(), e); 2218 } 2219 } 2220 2221 try { 2222 Application app = r.packageInfo.makeApplication(false, mInstrumentation); 2223 2224 if (localLOGV) Slog.v(TAG, "Performing launch of " + r); 2225 if (localLOGV) Slog.v( 2226 TAG, r + ": app=" + app 2227 + ", appName=" + app.getPackageName() 2228 + ", pkg=" + r.packageInfo.getPackageName() 2229 + ", comp=" + r.intent.getComponent().toShortString() 2230 + ", dir=" + r.packageInfo.getAppDir()); 2231 2232 if (activity != null) { 2233 Context appContext = createBaseContextForActivity(r, activity); 2234 CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager()); 2235 Configuration config = new Configuration(mCompatConfiguration); 2236 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity " 2237 + r.activityInfo.name + " with config " + config); 2238 activity.attach(appContext, this, getInstrumentation(), r.token, 2239 r.ident, app, r.intent, r.activityInfo, title, r.parent, 2240 r.embeddedID, r.lastNonConfigurationInstances, config); 2241 2242 if (customIntent != null) { 2243 activity.mIntent = customIntent; 2244 } 2245 r.lastNonConfigurationInstances = null; 2246 activity.mStartedActivity = false; 2247 int theme = r.activityInfo.getThemeResource(); 2248 if (theme != 0) { 2249 activity.setTheme(theme); 2250 } 2251 2252 activity.mCalled = false; 2253 mInstrumentation.callActivityOnCreate(activity, r.state); 2254 if (!activity.mCalled) { 2255 throw new SuperNotCalledException( 2256 "Activity " + r.intent.getComponent().toShortString() + 2257 " did not call through to super.onCreate()"); 2258 } 2259 r.activity = activity; 2260 r.stopped = true; 2261 if (!r.activity.mFinished) { 2262 activity.performStart(); 2263 r.stopped = false; 2264 } 2265 if (!r.activity.mFinished) { 2266 if (r.state != null) { 2267 mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state); 2268 } 2269 } 2270 if (!r.activity.mFinished) { 2271 activity.mCalled = false; 2272 mInstrumentation.callActivityOnPostCreate(activity, r.state); 2273 if (!activity.mCalled) { 2274 throw new SuperNotCalledException( 2275 "Activity " + r.intent.getComponent().toShortString() + 2276 " did not call through to super.onPostCreate()"); 2277 } 2278 } 2279 } 2280 r.paused = true; 2281 2282 mActivities.put(r.token, r); 2283 2284 } catch (SuperNotCalledException e) { 2285 throw e; 2286 2287 } catch (Exception e) { 2288 if (!mInstrumentation.onException(activity, e)) { 2289 throw new RuntimeException( 2290 "Unable to start activity " + component 2291 + ": " + e.toString(), e); 2292 } 2293 } 2294 2295 return activity; 2296 } 2297 2298 private Context createBaseContextForActivity(ActivityClientRecord r, 2299 final Activity activity) { 2300 ContextImpl appContext = new ContextImpl(); 2301 appContext.init(r.packageInfo, r.token, this); 2302 appContext.setOuterContext(activity); 2303 2304 // For debugging purposes, if the activity's package name contains the value of 2305 // the "debug.use-second-display" system property as a substring, then show 2306 // its content on a secondary display if there is one. 2307 Context baseContext = appContext; 2308 String pkgName = SystemProperties.get("debug.second-display.pkg"); 2309 if (pkgName != null && !pkgName.isEmpty() 2310 && r.packageInfo.mPackageName.contains(pkgName)) { 2311 DisplayManagerGlobal dm = DisplayManagerGlobal.getInstance(); 2312 for (int displayId : dm.getDisplayIds()) { 2313 if (displayId != Display.DEFAULT_DISPLAY) { 2314 Display display = dm.getRealDisplay(displayId, r.token); 2315 baseContext = appContext.createDisplayContext(display); 2316 break; 2317 } 2318 } 2319 } 2320 return baseContext; 2321 } 2322 2323 private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { 2324 // If we are getting ready to gc after going to the background, well 2325 // we are back active so skip it. 2326 unscheduleGcIdler(); 2327 2328 if (r.profileFd != null) { 2329 mProfiler.setProfiler(r.profileFile, r.profileFd); 2330 mProfiler.startProfiling(); 2331 mProfiler.autoStopProfiler = r.autoStopProfiler; 2332 } 2333 2334 // Make sure we are running with the most recent config. 2335 handleConfigurationChanged(null, null); 2336 2337 if (localLOGV) Slog.v( 2338 TAG, "Handling launch of " + r); 2339 Activity a = performLaunchActivity(r, customIntent); 2340 2341 if (a != null) { 2342 r.createdConfig = new Configuration(mConfiguration); 2343 Bundle oldState = r.state; 2344 handleResumeActivity(r.token, false, r.isForward, 2345 !r.activity.mFinished && !r.startsNotResumed); 2346 2347 if (!r.activity.mFinished && r.startsNotResumed) { 2348 // The activity manager actually wants this one to start out 2349 // paused, because it needs to be visible but isn't in the 2350 // foreground. We accomplish this by going through the 2351 // normal startup (because activities expect to go through 2352 // onResume() the first time they run, before their window 2353 // is displayed), and then pausing it. However, in this case 2354 // we do -not- need to do the full pause cycle (of freezing 2355 // and such) because the activity manager assumes it can just 2356 // retain the current state it has. 2357 try { 2358 r.activity.mCalled = false; 2359 mInstrumentation.callActivityOnPause(r.activity); 2360 // We need to keep around the original state, in case 2361 // we need to be created again. But we only do this 2362 // for pre-Honeycomb apps, which always save their state 2363 // when pausing, so we can not have them save their state 2364 // when restarting from a paused state. For HC and later, 2365 // we want to (and can) let the state be saved as the normal 2366 // part of stopping the activity. 2367 if (r.isPreHoneycomb()) { 2368 r.state = oldState; 2369 } 2370 if (!r.activity.mCalled) { 2371 throw new SuperNotCalledException( 2372 "Activity " + r.intent.getComponent().toShortString() + 2373 " did not call through to super.onPause()"); 2374 } 2375 2376 } catch (SuperNotCalledException e) { 2377 throw e; 2378 2379 } catch (Exception e) { 2380 if (!mInstrumentation.onException(r.activity, e)) { 2381 throw new RuntimeException( 2382 "Unable to pause activity " 2383 + r.intent.getComponent().toShortString() 2384 + ": " + e.toString(), e); 2385 } 2386 } 2387 r.paused = true; 2388 } 2389 } else { 2390 // If there was an error, for any reason, tell the activity 2391 // manager to stop us. 2392 try { 2393 ActivityManagerNative.getDefault() 2394 .finishActivity(r.token, Activity.RESULT_CANCELED, null); 2395 } catch (RemoteException ex) { 2396 // Ignore 2397 } 2398 } 2399 } 2400 2401 private void deliverNewIntents(ActivityClientRecord r, 2402 List<Intent> intents) { 2403 final int N = intents.size(); 2404 for (int i=0; i<N; i++) { 2405 Intent intent = intents.get(i); 2406 intent.setExtrasClassLoader(r.activity.getClassLoader()); 2407 r.activity.mFragments.noteStateNotSaved(); 2408 mInstrumentation.callActivityOnNewIntent(r.activity, intent); 2409 } 2410 } 2411 2412 public final void performNewIntents(IBinder token, 2413 List<Intent> intents) { 2414 ActivityClientRecord r = mActivities.get(token); 2415 if (r != null) { 2416 final boolean resumed = !r.paused; 2417 if (resumed) { 2418 r.activity.mTemporaryPause = true; 2419 mInstrumentation.callActivityOnPause(r.activity); 2420 } 2421 deliverNewIntents(r, intents); 2422 if (resumed) { 2423 r.activity.performResume(); 2424 r.activity.mTemporaryPause = false; 2425 } 2426 } 2427 } 2428 2429 private void handleNewIntent(NewIntentData data) { 2430 performNewIntents(data.token, data.intents); 2431 } 2432 2433 public void handleRequestActivityExtras(RequestActivityExtras cmd) { 2434 Bundle data = new Bundle(); 2435 ActivityClientRecord r = mActivities.get(cmd.activityToken); 2436 if (r != null) { 2437 r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data); 2438 r.activity.onProvideAssistData(data); 2439 } 2440 if (data.isEmpty()) { 2441 data = null; 2442 } 2443 IActivityManager mgr = ActivityManagerNative.getDefault(); 2444 try { 2445 mgr.reportTopActivityExtras(cmd.requestToken, data); 2446 } catch (RemoteException e) { 2447 } 2448 } 2449 2450 private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>(); 2451 2452 /** 2453 * Return the Intent that's currently being handled by a 2454 * BroadcastReceiver on this thread, or null if none. 2455 * @hide 2456 */ 2457 public static Intent getIntentBeingBroadcast() { 2458 return sCurrentBroadcastIntent.get(); 2459 } 2460 2461 private void handleReceiver(ReceiverData data) { 2462 // If we are getting ready to gc after going to the background, well 2463 // we are back active so skip it. 2464 unscheduleGcIdler(); 2465 2466 String component = data.intent.getComponent().getClassName(); 2467 2468 LoadedApk packageInfo = getPackageInfoNoCheck( 2469 data.info.applicationInfo, data.compatInfo); 2470 2471 IActivityManager mgr = ActivityManagerNative.getDefault(); 2472 2473 BroadcastReceiver receiver; 2474 try { 2475 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2476 data.intent.setExtrasClassLoader(cl); 2477 data.setExtrasClassLoader(cl); 2478 receiver = (BroadcastReceiver)cl.loadClass(component).newInstance(); 2479 } catch (Exception e) { 2480 if (DEBUG_BROADCAST) Slog.i(TAG, 2481 "Finishing failed broadcast to " + data.intent.getComponent()); 2482 data.sendFinished(mgr); 2483 throw new RuntimeException( 2484 "Unable to instantiate receiver " + component 2485 + ": " + e.toString(), e); 2486 } 2487 2488 try { 2489 Application app = packageInfo.makeApplication(false, mInstrumentation); 2490 2491 if (localLOGV) Slog.v( 2492 TAG, "Performing receive of " + data.intent 2493 + ": app=" + app 2494 + ", appName=" + app.getPackageName() 2495 + ", pkg=" + packageInfo.getPackageName() 2496 + ", comp=" + data.intent.getComponent().toShortString() 2497 + ", dir=" + packageInfo.getAppDir()); 2498 2499 ContextImpl context = (ContextImpl)app.getBaseContext(); 2500 sCurrentBroadcastIntent.set(data.intent); 2501 receiver.setPendingResult(data); 2502 receiver.onReceive(context.getReceiverRestrictedContext(), 2503 data.intent); 2504 } catch (Exception e) { 2505 if (DEBUG_BROADCAST) Slog.i(TAG, 2506 "Finishing failed broadcast to " + data.intent.getComponent()); 2507 data.sendFinished(mgr); 2508 if (!mInstrumentation.onException(receiver, e)) { 2509 throw new RuntimeException( 2510 "Unable to start receiver " + component 2511 + ": " + e.toString(), e); 2512 } 2513 } finally { 2514 sCurrentBroadcastIntent.set(null); 2515 } 2516 2517 if (receiver.getPendingResult() != null) { 2518 data.finish(); 2519 } 2520 } 2521 2522 // Instantiate a BackupAgent and tell it that it's alive 2523 private void handleCreateBackupAgent(CreateBackupAgentData data) { 2524 if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data); 2525 2526 // Sanity check the requested target package's uid against ours 2527 try { 2528 PackageInfo requestedPackage = getPackageManager().getPackageInfo( 2529 data.appInfo.packageName, 0, UserHandle.myUserId()); 2530 if (requestedPackage.applicationInfo.uid != Process.myUid()) { 2531 Slog.w(TAG, "Asked to instantiate non-matching package " 2532 + data.appInfo.packageName); 2533 return; 2534 } 2535 } catch (RemoteException e) { 2536 Slog.e(TAG, "Can't reach package manager", e); 2537 return; 2538 } 2539 2540 // no longer idle; we have backup work to do 2541 unscheduleGcIdler(); 2542 2543 // instantiate the BackupAgent class named in the manifest 2544 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2545 String packageName = packageInfo.mPackageName; 2546 if (packageName == null) { 2547 Slog.d(TAG, "Asked to create backup agent for nonexistent package"); 2548 return; 2549 } 2550 2551 if (mBackupAgents.get(packageName) != null) { 2552 Slog.d(TAG, "BackupAgent " + " for " + packageName 2553 + " already exists"); 2554 return; 2555 } 2556 2557 BackupAgent agent = null; 2558 String classname = data.appInfo.backupAgentName; 2559 2560 // full backup operation but no app-supplied agent? use the default implementation 2561 if (classname == null && (data.backupMode == IApplicationThread.BACKUP_MODE_FULL 2562 || data.backupMode == IApplicationThread.BACKUP_MODE_RESTORE_FULL)) { 2563 classname = "android.app.backup.FullBackupAgent"; 2564 } 2565 2566 try { 2567 IBinder binder = null; 2568 try { 2569 if (DEBUG_BACKUP) Slog.v(TAG, "Initializing agent class " + classname); 2570 2571 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2572 agent = (BackupAgent) cl.loadClass(classname).newInstance(); 2573 2574 // set up the agent's context 2575 ContextImpl context = new ContextImpl(); 2576 context.init(packageInfo, null, this); 2577 context.setOuterContext(agent); 2578 agent.attach(context); 2579 2580 agent.onCreate(); 2581 binder = agent.onBind(); 2582 mBackupAgents.put(packageName, agent); 2583 } catch (Exception e) { 2584 // If this is during restore, fail silently; otherwise go 2585 // ahead and let the user see the crash. 2586 Slog.e(TAG, "Agent threw during creation: " + e); 2587 if (data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE 2588 && data.backupMode != IApplicationThread.BACKUP_MODE_RESTORE_FULL) { 2589 throw e; 2590 } 2591 // falling through with 'binder' still null 2592 } 2593 2594 // tell the OS that we're live now 2595 try { 2596 ActivityManagerNative.getDefault().backupAgentCreated(packageName, binder); 2597 } catch (RemoteException e) { 2598 // nothing to do. 2599 } 2600 } catch (Exception e) { 2601 throw new RuntimeException("Unable to create BackupAgent " 2602 + classname + ": " + e.toString(), e); 2603 } 2604 } 2605 2606 // Tear down a BackupAgent 2607 private void handleDestroyBackupAgent(CreateBackupAgentData data) { 2608 if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data); 2609 2610 LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 2611 String packageName = packageInfo.mPackageName; 2612 BackupAgent agent = mBackupAgents.get(packageName); 2613 if (agent != null) { 2614 try { 2615 agent.onDestroy(); 2616 } catch (Exception e) { 2617 Slog.w(TAG, "Exception thrown in onDestroy by backup agent of " + data.appInfo); 2618 e.printStackTrace(); 2619 } 2620 mBackupAgents.remove(packageName); 2621 } else { 2622 Slog.w(TAG, "Attempt to destroy unknown backup agent " + data); 2623 } 2624 } 2625 2626 private void handleCreateService(CreateServiceData data) { 2627 // If we are getting ready to gc after going to the background, well 2628 // we are back active so skip it. 2629 unscheduleGcIdler(); 2630 2631 LoadedApk packageInfo = getPackageInfoNoCheck( 2632 data.info.applicationInfo, data.compatInfo); 2633 Service service = null; 2634 try { 2635 java.lang.ClassLoader cl = packageInfo.getClassLoader(); 2636 service = (Service) cl.loadClass(data.info.name).newInstance(); 2637 } catch (Exception e) { 2638 if (!mInstrumentation.onException(service, e)) { 2639 throw new RuntimeException( 2640 "Unable to instantiate service " + data.info.name 2641 + ": " + e.toString(), e); 2642 } 2643 } 2644 2645 try { 2646 if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name); 2647 2648 ContextImpl context = new ContextImpl(); 2649 context.init(packageInfo, null, this); 2650 2651 Application app = packageInfo.makeApplication(false, mInstrumentation); 2652 context.setOuterContext(service); 2653 service.attach(context, this, data.info.name, data.token, app, 2654 ActivityManagerNative.getDefault()); 2655 service.onCreate(); 2656 mServices.put(data.token, service); 2657 try { 2658 ActivityManagerNative.getDefault().serviceDoneExecuting( 2659 data.token, 0, 0, 0); 2660 } catch (RemoteException e) { 2661 // nothing to do. 2662 } 2663 } catch (Exception e) { 2664 if (!mInstrumentation.onException(service, e)) { 2665 throw new RuntimeException( 2666 "Unable to create service " + data.info.name 2667 + ": " + e.toString(), e); 2668 } 2669 } 2670 } 2671 2672 private void handleBindService(BindServiceData data) { 2673 Service s = mServices.get(data.token); 2674 if (DEBUG_SERVICE) 2675 Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind); 2676 if (s != null) { 2677 try { 2678 data.intent.setExtrasClassLoader(s.getClassLoader()); 2679 try { 2680 if (!data.rebind) { 2681 IBinder binder = s.onBind(data.intent); 2682 ActivityManagerNative.getDefault().publishService( 2683 data.token, data.intent, binder); 2684 } else { 2685 s.onRebind(data.intent); 2686 ActivityManagerNative.getDefault().serviceDoneExecuting( 2687 data.token, 0, 0, 0); 2688 } 2689 ensureJitEnabled(); 2690 } catch (RemoteException ex) { 2691 } 2692 } catch (Exception e) { 2693 if (!mInstrumentation.onException(s, e)) { 2694 throw new RuntimeException( 2695 "Unable to bind to service " + s 2696 + " with " + data.intent + ": " + e.toString(), e); 2697 } 2698 } 2699 } 2700 } 2701 2702 private void handleUnbindService(BindServiceData data) { 2703 Service s = mServices.get(data.token); 2704 if (s != null) { 2705 try { 2706 data.intent.setExtrasClassLoader(s.getClassLoader()); 2707 boolean doRebind = s.onUnbind(data.intent); 2708 try { 2709 if (doRebind) { 2710 ActivityManagerNative.getDefault().unbindFinished( 2711 data.token, data.intent, doRebind); 2712 } else { 2713 ActivityManagerNative.getDefault().serviceDoneExecuting( 2714 data.token, 0, 0, 0); 2715 } 2716 } catch (RemoteException ex) { 2717 } 2718 } catch (Exception e) { 2719 if (!mInstrumentation.onException(s, e)) { 2720 throw new RuntimeException( 2721 "Unable to unbind to service " + s 2722 + " with " + data.intent + ": " + e.toString(), e); 2723 } 2724 } 2725 } 2726 } 2727 2728 private void handleDumpService(DumpComponentInfo info) { 2729 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2730 try { 2731 Service s = mServices.get(info.token); 2732 if (s != null) { 2733 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor())); 2734 s.dump(info.fd.getFileDescriptor(), pw, info.args); 2735 pw.flush(); 2736 } 2737 } finally { 2738 IoUtils.closeQuietly(info.fd); 2739 StrictMode.setThreadPolicy(oldPolicy); 2740 } 2741 } 2742 2743 private void handleDumpActivity(DumpComponentInfo info) { 2744 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2745 try { 2746 ActivityClientRecord r = mActivities.get(info.token); 2747 if (r != null && r.activity != null) { 2748 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor())); 2749 r.activity.dump(info.prefix, info.fd.getFileDescriptor(), pw, info.args); 2750 pw.flush(); 2751 } 2752 } finally { 2753 IoUtils.closeQuietly(info.fd); 2754 StrictMode.setThreadPolicy(oldPolicy); 2755 } 2756 } 2757 2758 private void handleDumpProvider(DumpComponentInfo info) { 2759 final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); 2760 try { 2761 ProviderClientRecord r = mLocalProviders.get(info.token); 2762 if (r != null && r.mLocalProvider != null) { 2763 PrintWriter pw = new PrintWriter(new FileOutputStream(info.fd.getFileDescriptor())); 2764 r.mLocalProvider.dump(info.fd.getFileDescriptor(), pw, info.args); 2765 pw.flush(); 2766 } 2767 } finally { 2768 IoUtils.closeQuietly(info.fd); 2769 StrictMode.setThreadPolicy(oldPolicy); 2770 } 2771 } 2772 2773 private void handleServiceArgs(ServiceArgsData data) { 2774 Service s = mServices.get(data.token); 2775 if (s != null) { 2776 try { 2777 if (data.args != null) { 2778 data.args.setExtrasClassLoader(s.getClassLoader()); 2779 } 2780 int res; 2781 if (!data.taskRemoved) { 2782 res = s.onStartCommand(data.args, data.flags, data.startId); 2783 } else { 2784 s.onTaskRemoved(data.args); 2785 res = Service.START_TASK_REMOVED_COMPLETE; 2786 } 2787 2788 QueuedWork.waitToFinish(); 2789 2790 try { 2791 ActivityManagerNative.getDefault().serviceDoneExecuting( 2792 data.token, 1, data.startId, res); 2793 } catch (RemoteException e) { 2794 // nothing to do. 2795 } 2796 ensureJitEnabled(); 2797 } catch (Exception e) { 2798 if (!mInstrumentation.onException(s, e)) { 2799 throw new RuntimeException( 2800 "Unable to start service " + s 2801 + " with " + data.args + ": " + e.toString(), e); 2802 } 2803 } 2804 } 2805 } 2806 2807 private void handleStopService(IBinder token) { 2808 Service s = mServices.remove(token); 2809 if (s != null) { 2810 try { 2811 if (localLOGV) Slog.v(TAG, "Destroying service " + s); 2812 s.onDestroy(); 2813 Context context = s.getBaseContext(); 2814 if (context instanceof ContextImpl) { 2815 final String who = s.getClassName(); 2816 ((ContextImpl) context).scheduleFinalCleanup(who, "Service"); 2817 } 2818 2819 QueuedWork.waitToFinish(); 2820 2821 try { 2822 ActivityManagerNative.getDefault().serviceDoneExecuting( 2823 token, 0, 0, 0); 2824 } catch (RemoteException e) { 2825 // nothing to do. 2826 } 2827 } catch (Exception e) { 2828 if (!mInstrumentation.onException(s, e)) { 2829 throw new RuntimeException( 2830 "Unable to stop service " + s 2831 + ": " + e.toString(), e); 2832 } 2833 } 2834 } 2835 //Slog.i(TAG, "Running services: " + mServices); 2836 } 2837 2838 public final ActivityClientRecord performResumeActivity(IBinder token, 2839 boolean clearHide) { 2840 ActivityClientRecord r = mActivities.get(token); 2841 if (localLOGV) Slog.v(TAG, "Performing resume of " + r 2842 + " finished=" + r.activity.mFinished); 2843 if (r != null && !r.activity.mFinished) { 2844 if (clearHide) { 2845 r.hideForNow = false; 2846 r.activity.mStartedActivity = false; 2847 } 2848 try { 2849 r.activity.mFragments.noteStateNotSaved(); 2850 if (r.pendingIntents != null) { 2851 deliverNewIntents(r, r.pendingIntents); 2852 r.pendingIntents = null; 2853 } 2854 if (r.pendingResults != null) { 2855 deliverResults(r, r.pendingResults); 2856 r.pendingResults = null; 2857 } 2858 r.activity.performResume(); 2859 2860 EventLog.writeEvent(LOG_ON_RESUME_CALLED, 2861 UserHandle.myUserId(), r.activity.getComponentName().getClassName()); 2862 2863 r.paused = false; 2864 r.stopped = false; 2865 r.state = null; 2866 } catch (Exception e) { 2867 if (!mInstrumentation.onException(r.activity, e)) { 2868 throw new RuntimeException( 2869 "Unable to resume activity " 2870 + r.intent.getComponent().toShortString() 2871 + ": " + e.toString(), e); 2872 } 2873 } 2874 } 2875 return r; 2876 } 2877 2878 static final void cleanUpPendingRemoveWindows(ActivityClientRecord r) { 2879 if (r.mPendingRemoveWindow != null) { 2880 r.mPendingRemoveWindowManager.removeViewImmediate(r.mPendingRemoveWindow); 2881 IBinder wtoken = r.mPendingRemoveWindow.getWindowToken(); 2882 if (wtoken != null) { 2883 WindowManagerGlobal.getInstance().closeAll(wtoken, 2884 r.activity.getClass().getName(), "Activity"); 2885 } 2886 } 2887 r.mPendingRemoveWindow = null; 2888 r.mPendingRemoveWindowManager = null; 2889 } 2890 2891 final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, 2892 boolean reallyResume) { 2893 // If we are getting ready to gc after going to the background, well 2894 // we are back active so skip it. 2895 unscheduleGcIdler(); 2896 2897 ActivityClientRecord r = performResumeActivity(token, clearHide); 2898 2899 if (r != null) { 2900 final Activity a = r.activity; 2901 2902 if (localLOGV) Slog.v( 2903 TAG, "Resume " + r + " started activity: " + 2904 a.mStartedActivity + ", hideForNow: " + r.hideForNow 2905 + ", finished: " + a.mFinished); 2906 2907 final int forwardBit = isForward ? 2908 WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0; 2909 2910 // If the window hasn't yet been added to the window manager, 2911 // and this guy didn't finish itself or start another activity, 2912 // then go ahead and add the window. 2913 boolean willBeVisible = !a.mStartedActivity; 2914 if (!willBeVisible) { 2915 try { 2916 willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible( 2917 a.getActivityToken()); 2918 } catch (RemoteException e) { 2919 } 2920 } 2921 if (r.window == null && !a.mFinished && willBeVisible) { 2922 r.window = r.activity.getWindow(); 2923 View decor = r.window.getDecorView(); 2924 decor.setVisibility(View.INVISIBLE); 2925 ViewManager wm = a.getWindowManager(); 2926 WindowManager.LayoutParams l = r.window.getAttributes(); 2927 a.mDecor = decor; 2928 l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; 2929 l.softInputMode |= forwardBit; 2930 if (a.mVisibleFromClient) { 2931 a.mWindowAdded = true; 2932 wm.addView(decor, l); 2933 } 2934 2935 // If the window has already been added, but during resume 2936 // we started another activity, then don't yet make the 2937 // window visible. 2938 } else if (!willBeVisible) { 2939 if (localLOGV) Slog.v( 2940 TAG, "Launch " + r + " mStartedActivity set"); 2941 r.hideForNow = true; 2942 } 2943 2944 // Get rid of anything left hanging around. 2945 cleanUpPendingRemoveWindows(r); 2946 2947 // The window is now visible if it has been added, we are not 2948 // simply finishing, and we are not starting another activity. 2949 if (!r.activity.mFinished && willBeVisible 2950 && r.activity.mDecor != null && !r.hideForNow) { 2951 if (r.newConfig != null) { 2952 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " 2953 + r.activityInfo.name + " with newConfig " + r.newConfig); 2954 performConfigurationChanged(r.activity, r.newConfig); 2955 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 2956 r.newConfig = null; 2957 } 2958 if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" 2959 + isForward); 2960 WindowManager.LayoutParams l = r.window.getAttributes(); 2961 if ((l.softInputMode 2962 & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) 2963 != forwardBit) { 2964 l.softInputMode = (l.softInputMode 2965 & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)) 2966 | forwardBit; 2967 if (r.activity.mVisibleFromClient) { 2968 ViewManager wm = a.getWindowManager(); 2969 View decor = r.window.getDecorView(); 2970 wm.updateViewLayout(decor, l); 2971 } 2972 } 2973 r.activity.mVisibleFromServer = true; 2974 mNumVisibleActivities++; 2975 if (r.activity.mVisibleFromClient) { 2976 r.activity.makeVisible(); 2977 } 2978 } 2979 2980 if (!r.onlyLocalRequest) { 2981 r.nextIdle = mNewActivities; 2982 mNewActivities = r; 2983 if (localLOGV) Slog.v( 2984 TAG, "Scheduling idle handler for " + r); 2985 Looper.myQueue().addIdleHandler(new Idler()); 2986 } 2987 r.onlyLocalRequest = false; 2988 2989 // Tell the activity manager we have resumed. 2990 if (reallyResume) { 2991 try { 2992 ActivityManagerNative.getDefault().activityResumed(token); 2993 } catch (RemoteException ex) { 2994 } 2995 } 2996 2997 } else { 2998 // If an exception was thrown when trying to resume, then 2999 // just end this activity. 3000 try { 3001 ActivityManagerNative.getDefault() 3002 .finishActivity(token, Activity.RESULT_CANCELED, null); 3003 } catch (RemoteException ex) { 3004 } 3005 } 3006 } 3007 3008 private int mThumbnailWidth = -1; 3009 private int mThumbnailHeight = -1; 3010 private Bitmap mAvailThumbnailBitmap = null; 3011 private Canvas mThumbnailCanvas = null; 3012 3013 private Bitmap createThumbnailBitmap(ActivityClientRecord r) { 3014 Bitmap thumbnail = mAvailThumbnailBitmap; 3015 try { 3016 if (thumbnail == null) { 3017 int w = mThumbnailWidth; 3018 int h; 3019 if (w < 0) { 3020 Resources res = r.activity.getResources(); 3021 mThumbnailHeight = h = 3022 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_height); 3023 3024 mThumbnailWidth = w = 3025 res.getDimensionPixelSize(com.android.internal.R.dimen.thumbnail_width); 3026 } else { 3027 h = mThumbnailHeight; 3028 } 3029 3030 // On platforms where we don't want thumbnails, set dims to (0,0) 3031 if ((w > 0) && (h > 0)) { 3032 thumbnail = Bitmap.createBitmap(r.activity.getResources().getDisplayMetrics(), 3033 w, h, THUMBNAIL_FORMAT); 3034 thumbnail.eraseColor(0); 3035 } 3036 } 3037 3038 if (thumbnail != null) { 3039 Canvas cv = mThumbnailCanvas; 3040 if (cv == null) { 3041 mThumbnailCanvas = cv = new Canvas(); 3042 } 3043 3044 cv.setBitmap(thumbnail); 3045 if (!r.activity.onCreateThumbnail(thumbnail, cv)) { 3046 mAvailThumbnailBitmap = thumbnail; 3047 thumbnail = null; 3048 } 3049 cv.setBitmap(null); 3050 } 3051 3052 } catch (Exception e) { 3053 if (!mInstrumentation.onException(r.activity, e)) { 3054 throw new RuntimeException( 3055 "Unable to create thumbnail of " 3056 + r.intent.getComponent().toShortString() 3057 + ": " + e.toString(), e); 3058 } 3059 thumbnail = null; 3060 } 3061 3062 return thumbnail; 3063 } 3064 3065 private void handlePauseActivity(IBinder token, boolean finished, 3066 boolean userLeaving, int configChanges) { 3067 ActivityClientRecord r = mActivities.get(token); 3068 if (r != null) { 3069 //Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r); 3070 if (userLeaving) { 3071 performUserLeavingActivity(r); 3072 } 3073 3074 r.activity.mConfigChangeFlags |= configChanges; 3075 performPauseActivity(token, finished, r.isPreHoneycomb()); 3076 3077 // Make sure any pending writes are now committed. 3078 if (r.isPreHoneycomb()) { 3079 QueuedWork.waitToFinish(); 3080 } 3081 3082 // Tell the activity manager we have paused. 3083 try { 3084 ActivityManagerNative.getDefault().activityPaused(token); 3085 } catch (RemoteException ex) { 3086 } 3087 } 3088 } 3089 3090 final void performUserLeavingActivity(ActivityClientRecord r) { 3091 mInstrumentation.callActivityOnUserLeaving(r.activity); 3092 } 3093 3094 final Bundle performPauseActivity(IBinder token, boolean finished, 3095 boolean saveState) { 3096 ActivityClientRecord r = mActivities.get(token); 3097 return r != null ? performPauseActivity(r, finished, saveState) : null; 3098 } 3099 3100 final Bundle performPauseActivity(ActivityClientRecord r, boolean finished, 3101 boolean saveState) { 3102 if (r.paused) { 3103 if (r.activity.mFinished) { 3104 // If we are finishing, we won't call onResume() in certain cases. 3105 // So here we likewise don't want to call onPause() if the activity 3106 // isn't resumed. 3107 return null; 3108 } 3109 RuntimeException e = new RuntimeException( 3110 "Performing pause of activity that is not resumed: " 3111 + r.intent.getComponent().toShortString()); 3112 Slog.e(TAG, e.getMessage(), e); 3113 } 3114 Bundle state = null; 3115 if (finished) { 3116 r.activity.mFinished = true; 3117 } 3118 try { 3119 // Next have the activity save its current state and managed dialogs... 3120 if (!r.activity.mFinished && saveState) { 3121 state = new Bundle(); 3122 state.setAllowFds(false); 3123 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 3124 r.state = state; 3125 } 3126 // Now we are idle. 3127 r.activity.mCalled = false; 3128 mInstrumentation.callActivityOnPause(r.activity); 3129 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3130 r.activity.getComponentName().getClassName()); 3131 if (!r.activity.mCalled) { 3132 throw new SuperNotCalledException( 3133 "Activity " + r.intent.getComponent().toShortString() + 3134 " did not call through to super.onPause()"); 3135 } 3136 3137 } catch (SuperNotCalledException e) { 3138 throw e; 3139 3140 } catch (Exception e) { 3141 if (!mInstrumentation.onException(r.activity, e)) { 3142 throw new RuntimeException( 3143 "Unable to pause activity " 3144 + r.intent.getComponent().toShortString() 3145 + ": " + e.toString(), e); 3146 } 3147 } 3148 r.paused = true; 3149 3150 // Notify any outstanding on paused listeners 3151 ArrayList<OnActivityPausedListener> listeners; 3152 synchronized (mOnPauseListeners) { 3153 listeners = mOnPauseListeners.remove(r.activity); 3154 } 3155 int size = (listeners != null ? listeners.size() : 0); 3156 for (int i = 0; i < size; i++) { 3157 listeners.get(i).onPaused(r.activity); 3158 } 3159 3160 return state; 3161 } 3162 3163 final void performStopActivity(IBinder token, boolean saveState) { 3164 ActivityClientRecord r = mActivities.get(token); 3165 performStopActivityInner(r, null, false, saveState); 3166 } 3167 3168 private static class StopInfo implements Runnable { 3169 ActivityClientRecord activity; 3170 Bundle state; 3171 Bitmap thumbnail; 3172 CharSequence description; 3173 3174 @Override public void run() { 3175 // Tell activity manager we have been stopped. 3176 try { 3177 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Reporting activity stopped: " + activity); 3178 ActivityManagerNative.getDefault().activityStopped( 3179 activity.token, state, thumbnail, description); 3180 } catch (RemoteException ex) { 3181 } 3182 } 3183 } 3184 3185 private static final class ProviderRefCount { 3186 public final IActivityManager.ContentProviderHolder holder; 3187 public final ProviderClientRecord client; 3188 public int stableCount; 3189 public int unstableCount; 3190 3191 // When this is set, the stable and unstable ref counts are 0 and 3192 // we have a pending operation scheduled to remove the ref count 3193 // from the activity manager. On the activity manager we are still 3194 // holding an unstable ref, though it is not reflected in the counts 3195 // here. 3196 public boolean removePending; 3197 3198 ProviderRefCount(IActivityManager.ContentProviderHolder inHolder, 3199 ProviderClientRecord inClient, int sCount, int uCount) { 3200 holder = inHolder; 3201 client = inClient; 3202 stableCount = sCount; 3203 unstableCount = uCount; 3204 } 3205 } 3206 3207 /** 3208 * Core implementation of stopping an activity. Note this is a little 3209 * tricky because the server's meaning of stop is slightly different 3210 * than our client -- for the server, stop means to save state and give 3211 * it the result when it is done, but the window may still be visible. 3212 * For the client, we want to call onStop()/onStart() to indicate when 3213 * the activity's UI visibillity changes. 3214 */ 3215 private void performStopActivityInner(ActivityClientRecord r, 3216 StopInfo info, boolean keepShown, boolean saveState) { 3217 if (localLOGV) Slog.v(TAG, "Performing stop of " + r); 3218 Bundle state = null; 3219 if (r != null) { 3220 if (!keepShown && r.stopped) { 3221 if (r.activity.mFinished) { 3222 // If we are finishing, we won't call onResume() in certain 3223 // cases. So here we likewise don't want to call onStop() 3224 // if the activity isn't resumed. 3225 return; 3226 } 3227 RuntimeException e = new RuntimeException( 3228 "Performing stop of activity that is not resumed: " 3229 + r.intent.getComponent().toShortString()); 3230 Slog.e(TAG, e.getMessage(), e); 3231 } 3232 3233 if (info != null) { 3234 try { 3235 // First create a thumbnail for the activity... 3236 // For now, don't create the thumbnail here; we are 3237 // doing that by doing a screen snapshot. 3238 info.thumbnail = null; //createThumbnailBitmap(r); 3239 info.description = r.activity.onCreateDescription(); 3240 } catch (Exception e) { 3241 if (!mInstrumentation.onException(r.activity, e)) { 3242 throw new RuntimeException( 3243 "Unable to save state of activity " 3244 + r.intent.getComponent().toShortString() 3245 + ": " + e.toString(), e); 3246 } 3247 } 3248 } 3249 3250 // Next have the activity save its current state and managed dialogs... 3251 if (!r.activity.mFinished && saveState) { 3252 if (r.state == null) { 3253 state = new Bundle(); 3254 state.setAllowFds(false); 3255 mInstrumentation.callActivityOnSaveInstanceState(r.activity, state); 3256 r.state = state; 3257 } else { 3258 state = r.state; 3259 } 3260 } 3261 3262 if (!keepShown) { 3263 try { 3264 // Now we are idle. 3265 r.activity.performStop(); 3266 } catch (Exception e) { 3267 if (!mInstrumentation.onException(r.activity, e)) { 3268 throw new RuntimeException( 3269 "Unable to stop activity " 3270 + r.intent.getComponent().toShortString() 3271 + ": " + e.toString(), e); 3272 } 3273 } 3274 r.stopped = true; 3275 } 3276 3277 r.paused = true; 3278 } 3279 } 3280 3281 private void updateVisibility(ActivityClientRecord r, boolean show) { 3282 View v = r.activity.mDecor; 3283 if (v != null) { 3284 if (show) { 3285 if (!r.activity.mVisibleFromServer) { 3286 r.activity.mVisibleFromServer = true; 3287 mNumVisibleActivities++; 3288 if (r.activity.mVisibleFromClient) { 3289 r.activity.makeVisible(); 3290 } 3291 } 3292 if (r.newConfig != null) { 3293 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " 3294 + r.activityInfo.name + " with new config " + r.newConfig); 3295 performConfigurationChanged(r.activity, r.newConfig); 3296 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig)); 3297 r.newConfig = null; 3298 } 3299 } else { 3300 if (r.activity.mVisibleFromServer) { 3301 r.activity.mVisibleFromServer = false; 3302 mNumVisibleActivities--; 3303 v.setVisibility(View.INVISIBLE); 3304 } 3305 } 3306 } 3307 } 3308 3309 private void handleStopActivity(IBinder token, boolean show, int configChanges) { 3310 ActivityClientRecord r = mActivities.get(token); 3311 r.activity.mConfigChangeFlags |= configChanges; 3312 3313 StopInfo info = new StopInfo(); 3314 performStopActivityInner(r, info, show, true); 3315 3316 if (localLOGV) Slog.v( 3317 TAG, "Finishing stop of " + r + ": show=" + show 3318 + " win=" + r.window); 3319 3320 updateVisibility(r, show); 3321 3322 // Make sure any pending writes are now committed. 3323 if (!r.isPreHoneycomb()) { 3324 QueuedWork.waitToFinish(); 3325 } 3326 3327 // Schedule the call to tell the activity manager we have 3328 // stopped. We don't do this immediately, because we want to 3329 // have a chance for any other pending work (in particular memory 3330 // trim requests) to complete before you tell the activity 3331 // manager to proceed and allow us to go fully into the background. 3332 info.activity = r; 3333 info.state = r.state; 3334 mH.post(info); 3335 } 3336 3337 final void performRestartActivity(IBinder token) { 3338 ActivityClientRecord r = mActivities.get(token); 3339 if (r.stopped) { 3340 r.activity.performRestart(); 3341 r.stopped = false; 3342 } 3343 } 3344 3345 private void handleWindowVisibility(IBinder token, boolean show) { 3346 ActivityClientRecord r = mActivities.get(token); 3347 3348 if (r == null) { 3349 Log.w(TAG, "handleWindowVisibility: no activity for token " + token); 3350 return; 3351 } 3352 3353 if (!show && !r.stopped) { 3354 performStopActivityInner(r, null, show, false); 3355 } else if (show && r.stopped) { 3356 // If we are getting ready to gc after going to the background, well 3357 // we are back active so skip it. 3358 unscheduleGcIdler(); 3359 3360 r.activity.performRestart(); 3361 r.stopped = false; 3362 } 3363 if (r.activity.mDecor != null) { 3364 if (false) Slog.v( 3365 TAG, "Handle window " + r + " visibility: " + show); 3366 updateVisibility(r, show); 3367 } 3368 } 3369 3370 private void handleSleeping(IBinder token, boolean sleeping) { 3371 ActivityClientRecord r = mActivities.get(token); 3372 3373 if (r == null) { 3374 Log.w(TAG, "handleSleeping: no activity for token " + token); 3375 return; 3376 } 3377 3378 if (sleeping) { 3379 if (!r.stopped && !r.isPreHoneycomb()) { 3380 try { 3381 // Now we are idle. 3382 r.activity.performStop(); 3383 } catch (Exception e) { 3384 if (!mInstrumentation.onException(r.activity, e)) { 3385 throw new RuntimeException( 3386 "Unable to stop activity " 3387 + r.intent.getComponent().toShortString() 3388 + ": " + e.toString(), e); 3389 } 3390 } 3391 r.stopped = true; 3392 } 3393 3394 // Make sure any pending writes are now committed. 3395 if (!r.isPreHoneycomb()) { 3396 QueuedWork.waitToFinish(); 3397 } 3398 3399 // Tell activity manager we slept. 3400 try { 3401 ActivityManagerNative.getDefault().activitySlept(r.token); 3402 } catch (RemoteException ex) { 3403 } 3404 } else { 3405 if (r.stopped && r.activity.mVisibleFromServer) { 3406 r.activity.performRestart(); 3407 r.stopped = false; 3408 } 3409 } 3410 } 3411 3412 private void handleSetCoreSettings(Bundle coreSettings) { 3413 synchronized (mPackages) { 3414 mCoreSettings = coreSettings; 3415 } 3416 } 3417 3418 private void handleUpdatePackageCompatibilityInfo(UpdateCompatibilityData data) { 3419 LoadedApk apk = peekPackageInfo(data.pkg, false); 3420 if (apk != null) { 3421 apk.setCompatibilityInfo(data.info); 3422 } 3423 apk = peekPackageInfo(data.pkg, true); 3424 if (apk != null) { 3425 apk.setCompatibilityInfo(data.info); 3426 } 3427 handleConfigurationChanged(mConfiguration, data.info); 3428 WindowManagerGlobal.getInstance().reportNewConfiguration(mConfiguration); 3429 } 3430 3431 private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) { 3432 final int N = results.size(); 3433 for (int i=0; i<N; i++) { 3434 ResultInfo ri = results.get(i); 3435 try { 3436 if (ri.mData != null) { 3437 ri.mData.setExtrasClassLoader(r.activity.getClassLoader()); 3438 } 3439 if (DEBUG_RESULTS) Slog.v(TAG, 3440 "Delivering result to activity " + r + " : " + ri); 3441 r.activity.dispatchActivityResult(ri.mResultWho, 3442 ri.mRequestCode, ri.mResultCode, ri.mData); 3443 } catch (Exception e) { 3444 if (!mInstrumentation.onException(r.activity, e)) { 3445 throw new RuntimeException( 3446 "Failure delivering result " + ri + " to activity " 3447 + r.intent.getComponent().toShortString() 3448 + ": " + e.toString(), e); 3449 } 3450 } 3451 } 3452 } 3453 3454 private void handleSendResult(ResultData res) { 3455 ActivityClientRecord r = mActivities.get(res.token); 3456 if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r); 3457 if (r != null) { 3458 final boolean resumed = !r.paused; 3459 if (!r.activity.mFinished && r.activity.mDecor != null 3460 && r.hideForNow && resumed) { 3461 // We had hidden the activity because it started another 3462 // one... we have gotten a result back and we are not 3463 // paused, so make sure our window is visible. 3464 updateVisibility(r, true); 3465 } 3466 if (resumed) { 3467 try { 3468 // Now we are idle. 3469 r.activity.mCalled = false; 3470 r.activity.mTemporaryPause = true; 3471 mInstrumentation.callActivityOnPause(r.activity); 3472 if (!r.activity.mCalled) { 3473 throw new SuperNotCalledException( 3474 "Activity " + r.intent.getComponent().toShortString() 3475 + " did not call through to super.onPause()"); 3476 } 3477 } catch (SuperNotCalledException e) { 3478 throw e; 3479 } catch (Exception e) { 3480 if (!mInstrumentation.onException(r.activity, e)) { 3481 throw new RuntimeException( 3482 "Unable to pause activity " 3483 + r.intent.getComponent().toShortString() 3484 + ": " + e.toString(), e); 3485 } 3486 } 3487 } 3488 deliverResults(r, res.results); 3489 if (resumed) { 3490 r.activity.performResume(); 3491 r.activity.mTemporaryPause = false; 3492 } 3493 } 3494 } 3495 3496 public final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing) { 3497 return performDestroyActivity(token, finishing, 0, false); 3498 } 3499 3500 private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing, 3501 int configChanges, boolean getNonConfigInstance) { 3502 ActivityClientRecord r = mActivities.get(token); 3503 Class activityClass = null; 3504 if (localLOGV) Slog.v(TAG, "Performing finish of " + r); 3505 if (r != null) { 3506 activityClass = r.activity.getClass(); 3507 r.activity.mConfigChangeFlags |= configChanges; 3508 if (finishing) { 3509 r.activity.mFinished = true; 3510 } 3511 if (!r.paused) { 3512 try { 3513 r.activity.mCalled = false; 3514 mInstrumentation.callActivityOnPause(r.activity); 3515 EventLog.writeEvent(LOG_ON_PAUSE_CALLED, UserHandle.myUserId(), 3516 r.activity.getComponentName().getClassName()); 3517 if (!r.activity.mCalled) { 3518 throw new SuperNotCalledException( 3519 "Activity " + safeToComponentShortString(r.intent) 3520 + " did not call through to super.onPause()"); 3521 } 3522 } catch (SuperNotCalledException e) { 3523 throw e; 3524 } catch (Exception e) { 3525 if (!mInstrumentation.onException(r.activity, e)) { 3526 throw new RuntimeException( 3527 "Unable to pause activity " 3528 + safeToComponentShortString(r.intent) 3529 + ": " + e.toString(), e); 3530 } 3531 } 3532 r.paused = true; 3533 } 3534 if (!r.stopped) { 3535 try { 3536 r.activity.performStop(); 3537 } catch (SuperNotCalledException e) { 3538 throw e; 3539 } catch (Exception e) { 3540 if (!mInstrumentation.onException(r.activity, e)) { 3541 throw new RuntimeException( 3542 "Unable to stop activity " 3543 + safeToComponentShortString(r.intent) 3544 + ": " + e.toString(), e); 3545 } 3546 } 3547 r.stopped = true; 3548 } 3549 if (getNonConfigInstance) { 3550 try { 3551 r.lastNonConfigurationInstances 3552 = r.activity.retainNonConfigurationInstances(); 3553 } catch (Exception e) { 3554 if (!mInstrumentation.onException(r.activity, e)) { 3555 throw new RuntimeException( 3556 "Unable to retain activity " 3557 + r.intent.getComponent().toShortString() 3558 + ": " + e.toString(), e); 3559 } 3560 } 3561 } 3562 try { 3563 r.activity.mCalled = false; 3564 mInstrumentation.callActivityOnDestroy(r.activity); 3565 if (!r.activity.mCalled) { 3566 throw new SuperNotCalledException( 3567 "Activity " + safeToComponentShortString(r.intent) + 3568 " did not call through to super.onDestroy()"); 3569 } 3570 if (r.window != null) { 3571 r.window.closeAllPanels(); 3572 } 3573 } catch (SuperNotCalledException e) { 3574 throw e; 3575 } catch (Exception e) { 3576 if (!mInstrumentation.onException(r.activity, e)) { 3577 throw new RuntimeException( 3578 "Unable to destroy activity " + safeToComponentShortString(r.intent) 3579 + ": " + e.toString(), e); 3580 } 3581 } 3582 } 3583 mActivities.remove(token); 3584 StrictMode.decrementExpectedActivityCount(activityClass); 3585 return r; 3586 } 3587 3588 private static String safeToComponentShortString(Intent intent) { 3589 ComponentName component = intent.getComponent(); 3590 return component == null ? "[Unknown]" : component.toShortString(); 3591 } 3592 3593 private void handleDestroyActivity(IBinder token, boolean finishing, 3594 int configChanges, boolean getNonConfigInstance) { 3595 ActivityClientRecord r = performDestroyActivity(token, finishing, 3596 configChanges, getNonConfigInstance); 3597 if (r != null) { 3598 cleanUpPendingRemoveWindows(r); 3599 WindowManager wm = r.activity.getWindowManager(); 3600 View v = r.activity.mDecor; 3601 if (v != null) { 3602 if (r.activity.mVisibleFromServer) { 3603 mNumVisibleActivities--; 3604 } 3605 IBinder wtoken = v.getWindowToken(); 3606 if (r.activity.mWindowAdded) { 3607 if (r.onlyLocalRequest) { 3608 // Hold off on removing this until the new activity's 3609 // window is being added. 3610 r.mPendingRemoveWindow = v; 3611 r.mPendingRemoveWindowManager = wm; 3612 } else { 3613 wm.removeViewImmediate(v); 3614 } 3615 } 3616 if (wtoken != null && r.mPendingRemoveWindow == null) { 3617 WindowManagerGlobal.getInstance().closeAll(wtoken, 3618 r.activity.getClass().getName(), "Activity"); 3619 } 3620 r.activity.mDecor = null; 3621 } 3622 if (r.mPendingRemoveWindow == null) { 3623 // If we are delaying the removal of the activity window, then 3624 // we can't clean up all windows here. Note that we can't do 3625 // so later either, which means any windows that aren't closed 3626 // by the app will leak. Well we try to warning them a lot 3627 // about leaking windows, because that is a bug, so if they are 3628 // using this recreate facility then they get to live with leaks. 3629 WindowManagerGlobal.getInstance().closeAll(token, 3630 r.activity.getClass().getName(), "Activity"); 3631 } 3632 3633 // Mocked out contexts won't be participating in the normal 3634 // process lifecycle, but if we're running with a proper 3635 // ApplicationContext we need to have it tear down things 3636 // cleanly. 3637 Context c = r.activity.getBaseContext(); 3638 if (c instanceof ContextImpl) { 3639 ((ContextImpl) c).scheduleFinalCleanup( 3640 r.activity.getClass().getName(), "Activity"); 3641 } 3642 } 3643 if (finishing) { 3644 try { 3645 ActivityManagerNative.getDefault().activityDestroyed(token); 3646 } catch (RemoteException ex) { 3647 // If the system process has died, it's game over for everyone. 3648 } 3649 } 3650 } 3651 3652 public final void requestRelaunchActivity(IBinder token, 3653 List<ResultInfo> pendingResults, List<Intent> pendingNewIntents, 3654 int configChanges, boolean notResumed, Configuration config, 3655 boolean fromServer) { 3656 ActivityClientRecord target = null; 3657 3658 synchronized (mPackages) { 3659 for (int i=0; i<mRelaunchingActivities.size(); i++) { 3660 ActivityClientRecord r = mRelaunchingActivities.get(i); 3661 if (r.token == token) { 3662 target = r; 3663 if (pendingResults != null) { 3664 if (r.pendingResults != null) { 3665 r.pendingResults.addAll(pendingResults); 3666 } else { 3667 r.pendingResults = pendingResults; 3668 } 3669 } 3670 if (pendingNewIntents != null) { 3671 if (r.pendingIntents != null) { 3672 r.pendingIntents.addAll(pendingNewIntents); 3673 } else { 3674 r.pendingIntents = pendingNewIntents; 3675 } 3676 } 3677 break; 3678 } 3679 } 3680 3681 if (target == null) { 3682 target = new ActivityClientRecord(); 3683 target.token = token; 3684 target.pendingResults = pendingResults; 3685 target.pendingIntents = pendingNewIntents; 3686 if (!fromServer) { 3687 ActivityClientRecord existing = mActivities.get(token); 3688 if (existing != null) { 3689 target.startsNotResumed = existing.paused; 3690 } 3691 target.onlyLocalRequest = true; 3692 } 3693 mRelaunchingActivities.add(target); 3694 queueOrSendMessage(H.RELAUNCH_ACTIVITY, target); 3695 } 3696 3697 if (fromServer) { 3698 target.startsNotResumed = notResumed; 3699 target.onlyLocalRequest = false; 3700 } 3701 if (config != null) { 3702 target.createdConfig = config; 3703 } 3704 target.pendingConfigChanges |= configChanges; 3705 } 3706 } 3707 3708 private void handleRelaunchActivity(ActivityClientRecord tmp) { 3709 // If we are getting ready to gc after going to the background, well 3710 // we are back active so skip it. 3711 unscheduleGcIdler(); 3712 3713 Configuration changedConfig = null; 3714 int configChanges = 0; 3715 3716 // First: make sure we have the most recent configuration and most 3717 // recent version of the activity, or skip it if some previous call 3718 // had taken a more recent version. 3719 synchronized (mPackages) { 3720 int N = mRelaunchingActivities.size(); 3721 IBinder token = tmp.token; 3722 tmp = null; 3723 for (int i=0; i<N; i++) { 3724 ActivityClientRecord r = mRelaunchingActivities.get(i); 3725 if (r.token == token) { 3726 tmp = r; 3727 configChanges |= tmp.pendingConfigChanges; 3728 mRelaunchingActivities.remove(i); 3729 i--; 3730 N--; 3731 } 3732 } 3733 3734 if (tmp == null) { 3735 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Abort, activity not relaunching!"); 3736 return; 3737 } 3738 3739 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3740 + tmp.token + " with configChanges=0x" 3741 + Integer.toHexString(configChanges)); 3742 3743 if (mPendingConfiguration != null) { 3744 changedConfig = mPendingConfiguration; 3745 mPendingConfiguration = null; 3746 } 3747 } 3748 3749 if (tmp.createdConfig != null) { 3750 // If the activity manager is passing us its current config, 3751 // assume that is really what we want regardless of what we 3752 // may have pending. 3753 if (mConfiguration == null 3754 || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) 3755 && mConfiguration.diff(tmp.createdConfig) != 0)) { 3756 if (changedConfig == null 3757 || tmp.createdConfig.isOtherSeqNewer(changedConfig)) { 3758 changedConfig = tmp.createdConfig; 3759 } 3760 } 3761 } 3762 3763 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Relaunching activity " 3764 + tmp.token + ": changedConfig=" + changedConfig); 3765 3766 // If there was a pending configuration change, execute it first. 3767 if (changedConfig != null) { 3768 mCurDefaultDisplayDpi = changedConfig.densityDpi; 3769 updateDefaultDensity(); 3770 handleConfigurationChanged(changedConfig, null); 3771 } 3772 3773 ActivityClientRecord r = mActivities.get(tmp.token); 3774 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handling relaunch of " + r); 3775 if (r == null) { 3776 return; 3777 } 3778 3779 r.activity.mConfigChangeFlags |= configChanges; 3780 r.onlyLocalRequest = tmp.onlyLocalRequest; 3781 Intent currentIntent = r.activity.mIntent; 3782 3783 r.activity.mChangingConfigurations = true; 3784 3785 // Need to ensure state is saved. 3786 if (!r.paused) { 3787 performPauseActivity(r.token, false, r.isPreHoneycomb()); 3788 } 3789 if (r.state == null && !r.stopped && !r.isPreHoneycomb()) { 3790 r.state = new Bundle(); 3791 r.state.setAllowFds(false); 3792 mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state); 3793 } 3794 3795 handleDestroyActivity(r.token, false, configChanges, true); 3796 3797 r.activity = null; 3798 r.window = null; 3799 r.hideForNow = false; 3800 r.nextIdle = null; 3801 // Merge any pending results and pending intents; don't just replace them 3802 if (tmp.pendingResults != null) { 3803 if (r.pendingResults == null) { 3804 r.pendingResults = tmp.pendingResults; 3805 } else { 3806 r.pendingResults.addAll(tmp.pendingResults); 3807 } 3808 } 3809 if (tmp.pendingIntents != null) { 3810 if (r.pendingIntents == null) { 3811 r.pendingIntents = tmp.pendingIntents; 3812 } else { 3813 r.pendingIntents.addAll(tmp.pendingIntents); 3814 } 3815 } 3816 r.startsNotResumed = tmp.startsNotResumed; 3817 3818 handleLaunchActivity(r, currentIntent); 3819 } 3820 3821 private void handleRequestThumbnail(IBinder token) { 3822 ActivityClientRecord r = mActivities.get(token); 3823 Bitmap thumbnail = createThumbnailBitmap(r); 3824 CharSequence description = null; 3825 try { 3826 description = r.activity.onCreateDescription(); 3827 } catch (Exception e) { 3828 if (!mInstrumentation.onException(r.activity, e)) { 3829 throw new RuntimeException( 3830 "Unable to create description of activity " 3831 + r.intent.getComponent().toShortString() 3832 + ": " + e.toString(), e); 3833 } 3834 } 3835 //System.out.println("Reporting top thumbnail " + thumbnail); 3836 try { 3837 ActivityManagerNative.getDefault().reportThumbnail( 3838 token, thumbnail, description); 3839 } catch (RemoteException ex) { 3840 } 3841 } 3842 3843 ArrayList<ComponentCallbacks2> collectComponentCallbacks( 3844 boolean allActivities, Configuration newConfig) { 3845 ArrayList<ComponentCallbacks2> callbacks 3846 = new ArrayList<ComponentCallbacks2>(); 3847 3848 synchronized (mPackages) { 3849 final int N = mAllApplications.size(); 3850 for (int i=0; i<N; i++) { 3851 callbacks.add(mAllApplications.get(i)); 3852 } 3853 if (mActivities.size() > 0) { 3854 for (ActivityClientRecord ar : mActivities.values()) { 3855 Activity a = ar.activity; 3856 if (a != null) { 3857 Configuration thisConfig = applyConfigCompatMainThread( 3858 mCurDefaultDisplayDpi, newConfig, 3859 ar.packageInfo.getCompatibilityInfo()); 3860 if (!ar.activity.mFinished && (allActivities || !ar.paused)) { 3861 // If the activity is currently resumed, its configuration 3862 // needs to change right now. 3863 callbacks.add(a); 3864 } else if (thisConfig != null) { 3865 // Otherwise, we will tell it about the change 3866 // the next time it is resumed or shown. Note that 3867 // the activity manager may, before then, decide the 3868 // activity needs to be destroyed to handle its new 3869 // configuration. 3870 if (DEBUG_CONFIGURATION) { 3871 Slog.v(TAG, "Setting activity " 3872 + ar.activityInfo.name + " newConfig=" + thisConfig); 3873 } 3874 ar.newConfig = thisConfig; 3875 } 3876 } 3877 } 3878 } 3879 if (mServices.size() > 0) { 3880 for (Service service : mServices.values()) { 3881 callbacks.add(service); 3882 } 3883 } 3884 } 3885 synchronized (mProviderMap) { 3886 if (mLocalProviders.size() > 0) { 3887 for (ProviderClientRecord providerClientRecord : mLocalProviders.values()) { 3888 callbacks.add(providerClientRecord.mLocalProvider); 3889 } 3890 } 3891 } 3892 3893 return callbacks; 3894 } 3895 3896 private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) { 3897 // Only for Activity objects, check that they actually call up to their 3898 // superclass implementation. ComponentCallbacks2 is an interface, so 3899 // we check the runtime type and act accordingly. 3900 Activity activity = (cb instanceof Activity) ? (Activity) cb : null; 3901 if (activity != null) { 3902 activity.mCalled = false; 3903 } 3904 3905 boolean shouldChangeConfig = false; 3906 if ((activity == null) || (activity.mCurrentConfig == null)) { 3907 shouldChangeConfig = true; 3908 } else { 3909 3910 // If the new config is the same as the config this Activity 3911 // is already running with then don't bother calling 3912 // onConfigurationChanged 3913 int diff = activity.mCurrentConfig.diff(config); 3914 if (diff != 0) { 3915 // If this activity doesn't handle any of the config changes 3916 // then don't bother calling onConfigurationChanged as we're 3917 // going to destroy it. 3918 if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) { 3919 shouldChangeConfig = true; 3920 } 3921 } 3922 } 3923 3924 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb 3925 + ": shouldChangeConfig=" + shouldChangeConfig); 3926 if (shouldChangeConfig) { 3927 cb.onConfigurationChanged(config); 3928 3929 if (activity != null) { 3930 if (!activity.mCalled) { 3931 throw new SuperNotCalledException( 3932 "Activity " + activity.getLocalClassName() + 3933 " did not call through to super.onConfigurationChanged()"); 3934 } 3935 activity.mConfigChangeFlags = 0; 3936 activity.mCurrentConfig = new Configuration(config); 3937 } 3938 } 3939 } 3940 3941 public final void applyConfigurationToResources(Configuration config) { 3942 synchronized (mPackages) { 3943 applyConfigurationToResourcesLocked(config, null); 3944 } 3945 } 3946 3947 final boolean applyConfigurationToResourcesLocked(Configuration config, 3948 CompatibilityInfo compat) { 3949 if (mResConfiguration == null) { 3950 mResConfiguration = new Configuration(); 3951 } 3952 if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) { 3953 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq=" 3954 + mResConfiguration.seq + ", newSeq=" + config.seq); 3955 return false; 3956 } 3957 int changes = mResConfiguration.updateFrom(config); 3958 flushDisplayMetricsLocked(); 3959 DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY); 3960 3961 if (compat != null && (mResCompatibilityInfo == null || 3962 !mResCompatibilityInfo.equals(compat))) { 3963 mResCompatibilityInfo = compat; 3964 changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT 3965 | ActivityInfo.CONFIG_SCREEN_SIZE 3966 | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; 3967 } 3968 3969 // set it for java, this also affects newly created Resources 3970 if (config.locale != null) { 3971 Locale.setDefault(config.locale); 3972 } 3973 3974 Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat); 3975 3976 ApplicationPackageManager.configurationChanged(); 3977 //Slog.i(TAG, "Configuration changed in " + currentPackageName()); 3978 3979 Configuration tmpConfig = null; 3980 3981 Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it = 3982 mActiveResources.entrySet().iterator(); 3983 while (it.hasNext()) { 3984 Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next(); 3985 Resources r = entry.getValue().get(); 3986 if (r != null) { 3987 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources " 3988 + r + " config to: " + config); 3989 int displayId = entry.getKey().mDisplayId; 3990 boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); 3991 DisplayMetrics dm = defaultDisplayMetrics; 3992 Configuration overrideConfig = entry.getKey().mOverrideConfiguration; 3993 if (!isDefaultDisplay || overrideConfig != null) { 3994 if (tmpConfig == null) { 3995 tmpConfig = new Configuration(); 3996 } 3997 tmpConfig.setTo(config); 3998 if (!isDefaultDisplay) { 3999 dm = getDisplayMetricsLocked(displayId); 4000 applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig); 4001 } 4002 if (overrideConfig != null) { 4003 tmpConfig.updateFrom(overrideConfig); 4004 } 4005 r.updateConfiguration(tmpConfig, dm, compat); 4006 } else { 4007 r.updateConfiguration(config, dm, compat); 4008 } 4009 //Slog.i(TAG, "Updated app resources " + v.getKey() 4010 // + " " + r + ": " + r.getConfiguration()); 4011 } else { 4012 //Slog.i(TAG, "Removing old resources " + v.getKey()); 4013 it.remove(); 4014 } 4015 } 4016 4017 return changes != 0; 4018 } 4019 4020 final void applyNonDefaultDisplayMetricsToConfigurationLocked( 4021 DisplayMetrics dm, Configuration config) { 4022 config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH; 4023 config.densityDpi = dm.densityDpi; 4024 config.screenWidthDp = (int)(dm.widthPixels / dm.density); 4025 config.screenHeightDp = (int)(dm.heightPixels / dm.density); 4026 int sl = Configuration.resetScreenLayout(config.screenLayout); 4027 if (dm.widthPixels > dm.heightPixels) { 4028 config.orientation = Configuration.ORIENTATION_LANDSCAPE; 4029 config.screenLayout = Configuration.reduceScreenLayout(sl, 4030 config.screenWidthDp, config.screenHeightDp); 4031 } else { 4032 config.orientation = Configuration.ORIENTATION_PORTRAIT; 4033 config.screenLayout = Configuration.reduceScreenLayout(sl, 4034 config.screenHeightDp, config.screenWidthDp); 4035 } 4036 config.smallestScreenWidthDp = config.screenWidthDp; // assume screen does not rotate 4037 config.compatScreenWidthDp = config.screenWidthDp; 4038 config.compatScreenHeightDp = config.screenHeightDp; 4039 config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp; 4040 } 4041 4042 final Configuration applyCompatConfiguration(int displayDensity) { 4043 Configuration config = mConfiguration; 4044 if (mCompatConfiguration == null) { 4045 mCompatConfiguration = new Configuration(); 4046 } 4047 mCompatConfiguration.setTo(mConfiguration); 4048 if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) { 4049 mResCompatibilityInfo.applyToConfiguration(displayDensity, mCompatConfiguration); 4050 config = mCompatConfiguration; 4051 } 4052 return config; 4053 } 4054 4055 final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) { 4056 4057 int configDiff = 0; 4058 4059 synchronized (mPackages) { 4060 if (mPendingConfiguration != null) { 4061 if (!mPendingConfiguration.isOtherSeqNewer(config)) { 4062 config = mPendingConfiguration; 4063 mCurDefaultDisplayDpi = config.densityDpi; 4064 updateDefaultDensity(); 4065 } 4066 mPendingConfiguration = null; 4067 } 4068 4069 if (config == null) { 4070 return; 4071 } 4072 4073 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle configuration changed: " 4074 + config); 4075 4076 applyConfigurationToResourcesLocked(config, compat); 4077 4078 if (mConfiguration == null) { 4079 mConfiguration = new Configuration(); 4080 } 4081 if (!mConfiguration.isOtherSeqNewer(config) && compat == null) { 4082 return; 4083 } 4084 configDiff = mConfiguration.diff(config); 4085 mConfiguration.updateFrom(config); 4086 config = applyCompatConfiguration(mCurDefaultDisplayDpi); 4087 } 4088 4089 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config); 4090 4091 // Cleanup hardware accelerated stuff 4092 WindowManagerGlobal.getInstance().trimLocalMemory(); 4093 4094 freeTextLayoutCachesIfNeeded(configDiff); 4095 4096 if (callbacks != null) { 4097 final int N = callbacks.size(); 4098 for (int i=0; i<N; i++) { 4099 performConfigurationChanged(callbacks.get(i), config); 4100 } 4101 } 4102 } 4103 4104 final void freeTextLayoutCachesIfNeeded(int configDiff) { 4105 if (configDiff != 0) { 4106 // Ask text layout engine to free its caches if there is a locale change 4107 boolean hasLocaleConfigChange = ((configDiff & ActivityInfo.CONFIG_LOCALE) != 0); 4108 if (hasLocaleConfigChange) { 4109 Canvas.freeTextLayoutCaches(); 4110 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Cleared TextLayout Caches"); 4111 } 4112 } 4113 } 4114 4115 final void handleActivityConfigurationChanged(IBinder token) { 4116 ActivityClientRecord r = mActivities.get(token); 4117 if (r == null || r.activity == null) { 4118 return; 4119 } 4120 4121 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " 4122 + r.activityInfo.name); 4123 4124 performConfigurationChanged(r.activity, mCompatConfiguration); 4125 4126 freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); 4127 } 4128 4129 final void handleProfilerControl(boolean start, ProfilerControlData pcd, int profileType) { 4130 if (start) { 4131 try { 4132 switch (profileType) { 4133 default: 4134 mProfiler.setProfiler(pcd.path, pcd.fd); 4135 mProfiler.autoStopProfiler = false; 4136 mProfiler.startProfiling(); 4137 break; 4138 } 4139 } catch (RuntimeException e) { 4140 Slog.w(TAG, "Profiling failed on path " + pcd.path 4141 + " -- can the process access this path?"); 4142 } finally { 4143 try { 4144 pcd.fd.close(); 4145 } catch (IOException e) { 4146 Slog.w(TAG, "Failure closing profile fd", e); 4147 } 4148 } 4149 } else { 4150 switch (profileType) { 4151 default: 4152 mProfiler.stopProfiling(); 4153 break; 4154 } 4155 } 4156 } 4157 4158 static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { 4159 if (managed) { 4160 try { 4161 Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); 4162 } catch (IOException e) { 4163 Slog.w(TAG, "Managed heap dump failed on path " + dhd.path 4164 + " -- can the process access this path?"); 4165 } finally { 4166 try { 4167 dhd.fd.close(); 4168 } catch (IOException e) { 4169 Slog.w(TAG, "Failure closing profile fd", e); 4170 } 4171 } 4172 } else { 4173 Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); 4174 } 4175 } 4176 4177 final void handleDispatchPackageBroadcast(int cmd, String[] packages) { 4178 boolean hasPkgInfo = false; 4179 if (packages != null) { 4180 for (int i=packages.length-1; i>=0; i--) { 4181 //Slog.i(TAG, "Cleaning old package: " + packages[i]); 4182 if (!hasPkgInfo) { 4183 WeakReference<LoadedApk> ref; 4184 ref = mPackages.get(packages[i]); 4185 if (ref != null && ref.get() != null) { 4186 hasPkgInfo = true; 4187 } else { 4188 ref = mResourcePackages.get(packages[i]); 4189 if (ref != null && ref.get() != null) { 4190 hasPkgInfo = true; 4191 } 4192 } 4193 } 4194 mPackages.remove(packages[i]); 4195 mResourcePackages.remove(packages[i]); 4196 } 4197 } 4198 ApplicationPackageManager.handlePackageBroadcast(cmd, packages, 4199 hasPkgInfo); 4200 } 4201 4202 final void handleLowMemory() { 4203 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4204 4205 final int N = callbacks.size(); 4206 for (int i=0; i<N; i++) { 4207 callbacks.get(i).onLowMemory(); 4208 } 4209 4210 // Ask SQLite to free up as much memory as it can, mostly from its page caches. 4211 if (Process.myUid() != Process.SYSTEM_UID) { 4212 int sqliteReleased = SQLiteDatabase.releaseMemory(); 4213 EventLog.writeEvent(SQLITE_MEM_RELEASED_EVENT_LOG_TAG, sqliteReleased); 4214 } 4215 4216 // Ask graphics to free up as much as possible (font/image caches) 4217 Canvas.freeCaches(); 4218 4219 // Ask text layout engine to free also as much as possible 4220 Canvas.freeTextLayoutCaches(); 4221 4222 BinderInternal.forceGc("mem"); 4223 } 4224 4225 final void handleTrimMemory(int level) { 4226 if (DEBUG_MEMORY_TRIM) Slog.v(TAG, "Trimming memory to level: " + level); 4227 4228 final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance(); 4229 windowManager.startTrimMemory(level); 4230 4231 ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null); 4232 4233 final int N = callbacks.size(); 4234 for (int i = 0; i < N; i++) { 4235 callbacks.get(i).onTrimMemory(level); 4236 } 4237 4238 windowManager.endTrimMemory(); 4239 } 4240 4241 private void setupGraphicsSupport(LoadedApk info, File cacheDir) { 4242 if (Process.isIsolated()) { 4243 // Isolated processes aren't going to do UI. 4244 return; 4245 } 4246 try { 4247 int uid = Process.myUid(); 4248 String[] packages = getPackageManager().getPackagesForUid(uid); 4249 4250 // If there are several packages in this application we won't 4251 // initialize the graphics disk caches 4252 if (packages != null && packages.length == 1) { 4253 HardwareRenderer.setupDiskCache(cacheDir); 4254 RenderScript.setupDiskCache(cacheDir); 4255 } 4256 } catch (RemoteException e) { 4257 // Ignore 4258 } 4259 } 4260 4261 private void updateDefaultDensity() { 4262 if (mCurDefaultDisplayDpi != Configuration.DENSITY_DPI_UNDEFINED 4263 && mCurDefaultDisplayDpi != DisplayMetrics.DENSITY_DEVICE 4264 && !mDensityCompatMode) { 4265 Slog.i(TAG, "Switching default density from " 4266 + DisplayMetrics.DENSITY_DEVICE + " to " 4267 + mCurDefaultDisplayDpi); 4268 DisplayMetrics.DENSITY_DEVICE = mCurDefaultDisplayDpi; 4269 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4270 } 4271 } 4272 4273 private void handleBindApplication(AppBindData data) { 4274 mBoundApplication = data; 4275 mConfiguration = new Configuration(data.config); 4276 mCompatConfiguration = new Configuration(data.config); 4277 4278 mProfiler = new Profiler(); 4279 mProfiler.profileFile = data.initProfileFile; 4280 mProfiler.profileFd = data.initProfileFd; 4281 mProfiler.autoStopProfiler = data.initAutoStopProfiler; 4282 4283 // send up app name; do this *before* waiting for debugger 4284 Process.setArgV0(data.processName); 4285 android.ddm.DdmHandleAppName.setAppName(data.processName, 4286 UserHandle.myUserId()); 4287 4288 if (data.persistent) { 4289 // Persistent processes on low-memory devices do not get to 4290 // use hardware accelerated drawing, since this can add too much 4291 // overhead to the process. 4292 if (!ActivityManager.isHighEndGfx()) { 4293 HardwareRenderer.disable(false); 4294 } 4295 } 4296 4297 if (mProfiler.profileFd != null) { 4298 mProfiler.startProfiling(); 4299 } 4300 4301 // If the app is Honeycomb MR1 or earlier, switch its AsyncTask 4302 // implementation to use the pool executor. Normally, we use the 4303 // serialized executor as the default. This has to happen in the 4304 // main thread so the main looper is set right. 4305 if (data.appInfo.targetSdkVersion <= android.os.Build.VERSION_CODES.HONEYCOMB_MR1) { 4306 AsyncTask.setDefaultExecutor(AsyncTask.THREAD_POOL_EXECUTOR); 4307 } 4308 4309 /* 4310 * Before spawning a new process, reset the time zone to be the system time zone. 4311 * This needs to be done because the system time zone could have changed after the 4312 * the spawning of this process. Without doing this this process would have the incorrect 4313 * system time zone. 4314 */ 4315 TimeZone.setDefault(null); 4316 4317 /* 4318 * Initialize the default locale in this process for the reasons we set the time zone. 4319 */ 4320 Locale.setDefault(data.config.locale); 4321 4322 /* 4323 * Update the system configuration since its preloaded and might not 4324 * reflect configuration changes. The configuration object passed 4325 * in AppBindData can be safely assumed to be up to date 4326 */ 4327 applyConfigurationToResourcesLocked(data.config, data.compatInfo); 4328 mCurDefaultDisplayDpi = data.config.densityDpi; 4329 applyCompatConfiguration(mCurDefaultDisplayDpi); 4330 4331 data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); 4332 4333 /** 4334 * Switch this process to density compatibility mode if needed. 4335 */ 4336 if ((data.appInfo.flags&ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) 4337 == 0) { 4338 mDensityCompatMode = true; 4339 Bitmap.setDefaultDensity(DisplayMetrics.DENSITY_DEFAULT); 4340 } 4341 updateDefaultDensity(); 4342 4343 final ContextImpl appContext = new ContextImpl(); 4344 appContext.init(data.info, null, this); 4345 if (!Process.isIsolated()) { 4346 final File cacheDir = appContext.getCacheDir(); 4347 4348 if (cacheDir != null) { 4349 // Provide a usable directory for temporary files 4350 System.setProperty("java.io.tmpdir", cacheDir.getAbsolutePath()); 4351 4352 setupGraphicsSupport(data.info, cacheDir); 4353 } else { 4354 Log.e(TAG, "Unable to setupGraphicsSupport due to missing cache directory"); 4355 } 4356 } 4357 /** 4358 * For system applications on userdebug/eng builds, log stack 4359 * traces of disk and network access to dropbox for analysis. 4360 */ 4361 if ((data.appInfo.flags & 4362 (ApplicationInfo.FLAG_SYSTEM | 4363 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) { 4364 StrictMode.conditionallyEnableDebugLogging(); 4365 } 4366 4367 /** 4368 * For apps targetting SDK Honeycomb or later, we don't allow 4369 * network usage on the main event loop / UI thread. 4370 * 4371 * Note to those grepping: this is what ultimately throws 4372 * NetworkOnMainThreadException ... 4373 */ 4374 if (data.appInfo.targetSdkVersion > 9) { 4375 StrictMode.enableDeathOnNetwork(); 4376 } 4377 4378 if (data.debugMode != IApplicationThread.DEBUG_OFF) { 4379 // XXX should have option to change the port. 4380 Debug.changeDebugPort(8100); 4381 if (data.debugMode == IApplicationThread.DEBUG_WAIT) { 4382 Slog.w(TAG, "Application " + data.info.getPackageName() 4383 + " is waiting for the debugger on port 8100..."); 4384 4385 IActivityManager mgr = ActivityManagerNative.getDefault(); 4386 try { 4387 mgr.showWaitingForDebugger(mAppThread, true); 4388 } catch (RemoteException ex) { 4389 } 4390 4391 Debug.waitForDebugger(); 4392 4393 try { 4394 mgr.showWaitingForDebugger(mAppThread, false); 4395 } catch (RemoteException ex) { 4396 } 4397 4398 } else { 4399 Slog.w(TAG, "Application " + data.info.getPackageName() 4400 + " can be debugged on port 8100..."); 4401 } 4402 } 4403 4404 // Enable OpenGL tracing if required 4405 if (data.enableOpenGlTrace) { 4406 GLUtils.setTracingLevel(1); 4407 } 4408 4409 // Allow application-generated systrace messages if we're debuggable. 4410 boolean appTracingAllowed = (data.appInfo.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0; 4411 Trace.setAppTracingAllowed(appTracingAllowed); 4412 4413 /** 4414 * Initialize the default http proxy in this process for the reasons we set the time zone. 4415 */ 4416 IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); 4417 if (b != null) { 4418 // In pre-boot mode (doing initial launch to collect password), not 4419 // all system is up. This includes the connectivity service, so don't 4420 // crash if we can't get it. 4421 IConnectivityManager service = IConnectivityManager.Stub.asInterface(b); 4422 try { 4423 ProxyProperties proxyProperties = service.getProxy(); 4424 Proxy.setHttpProxySystemProperty(proxyProperties); 4425 } catch (RemoteException e) {} 4426 } 4427 4428 if (data.instrumentationName != null) { 4429 InstrumentationInfo ii = null; 4430 try { 4431 ii = appContext.getPackageManager(). 4432 getInstrumentationInfo(data.instrumentationName, 0); 4433 } catch (PackageManager.NameNotFoundException e) { 4434 } 4435 if (ii == null) { 4436 throw new RuntimeException( 4437 "Unable to find instrumentation info for: " 4438 + data.instrumentationName); 4439 } 4440 4441 mInstrumentationAppDir = ii.sourceDir; 4442 mInstrumentationAppLibraryDir = ii.nativeLibraryDir; 4443 mInstrumentationAppPackage = ii.packageName; 4444 mInstrumentedAppDir = data.info.getAppDir(); 4445 mInstrumentedAppLibraryDir = data.info.getLibDir(); 4446 4447 ApplicationInfo instrApp = new ApplicationInfo(); 4448 instrApp.packageName = ii.packageName; 4449 instrApp.sourceDir = ii.sourceDir; 4450 instrApp.publicSourceDir = ii.publicSourceDir; 4451 instrApp.dataDir = ii.dataDir; 4452 instrApp.nativeLibraryDir = ii.nativeLibraryDir; 4453 LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 4454 appContext.getClassLoader(), false, true); 4455 ContextImpl instrContext = new ContextImpl(); 4456 instrContext.init(pi, null, this); 4457 4458 try { 4459 java.lang.ClassLoader cl = instrContext.getClassLoader(); 4460 mInstrumentation = (Instrumentation) 4461 cl.loadClass(data.instrumentationName.getClassName()).newInstance(); 4462 } catch (Exception e) { 4463 throw new RuntimeException( 4464 "Unable to instantiate instrumentation " 4465 + data.instrumentationName + ": " + e.toString(), e); 4466 } 4467 4468 mInstrumentation.init(this, instrContext, appContext, 4469 new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher, 4470 data.instrumentationUiAutomationConnection); 4471 4472 if (mProfiler.profileFile != null && !ii.handleProfiling 4473 && mProfiler.profileFd == null) { 4474 mProfiler.handlingProfiling = true; 4475 File file = new File(mProfiler.profileFile); 4476 file.getParentFile().mkdirs(); 4477 Debug.startMethodTracing(file.toString(), 8 * 1024 * 1024); 4478 } 4479 4480 } else { 4481 mInstrumentation = new Instrumentation(); 4482 } 4483 4484 if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) { 4485 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit(); 4486 } 4487 4488 // Allow disk access during application and provider setup. This could 4489 // block processing ordered broadcasts, but later processing would 4490 // probably end up doing the same disk access. 4491 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites(); 4492 try { 4493 // If the app is being launched for full backup or restore, bring it up in 4494 // a restricted environment with the base application class. 4495 Application app = data.info.makeApplication(data.restrictedBackupMode, null); 4496 mInitialApplication = app; 4497 4498 // don't bring up providers in restricted mode; they may depend on the 4499 // app's custom Application class 4500 if (!data.restrictedBackupMode) { 4501 List<ProviderInfo> providers = data.providers; 4502 if (providers != null) { 4503 installContentProviders(app, providers); 4504 // For process that contains content providers, we want to 4505 // ensure that the JIT is enabled "at some point". 4506 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000); 4507 } 4508 } 4509 4510 // Do this after providers, since instrumentation tests generally start their 4511 // test thread at this point, and we don't want that racing. 4512 try { 4513 mInstrumentation.onCreate(data.instrumentationArgs); 4514 } 4515 catch (Exception e) { 4516 throw new RuntimeException( 4517 "Exception thrown in onCreate() of " 4518 + data.instrumentationName + ": " + e.toString(), e); 4519 } 4520 4521 try { 4522 mInstrumentation.callApplicationOnCreate(app); 4523 } catch (Exception e) { 4524 if (!mInstrumentation.onException(app, e)) { 4525 throw new RuntimeException( 4526 "Unable to create application " + app.getClass().getName() 4527 + ": " + e.toString(), e); 4528 } 4529 } 4530 } finally { 4531 StrictMode.setThreadPolicy(savedPolicy); 4532 } 4533 } 4534 4535 /*package*/ final void finishInstrumentation(int resultCode, Bundle results) { 4536 IActivityManager am = ActivityManagerNative.getDefault(); 4537 if (mProfiler.profileFile != null && mProfiler.handlingProfiling 4538 && mProfiler.profileFd == null) { 4539 Debug.stopMethodTracing(); 4540 } 4541 //Slog.i(TAG, "am: " + ActivityManagerNative.getDefault() 4542 // + ", app thr: " + mAppThread); 4543 try { 4544 am.finishInstrumentation(mAppThread, resultCode, results); 4545 } catch (RemoteException ex) { 4546 } 4547 } 4548 4549 private void installContentProviders( 4550 Context context, List<ProviderInfo> providers) { 4551 final ArrayList<IActivityManager.ContentProviderHolder> results = 4552 new ArrayList<IActivityManager.ContentProviderHolder>(); 4553 4554 for (ProviderInfo cpi : providers) { 4555 if (DEBUG_PROVIDER) { 4556 StringBuilder buf = new StringBuilder(128); 4557 buf.append("Pub "); 4558 buf.append(cpi.authority); 4559 buf.append(": "); 4560 buf.append(cpi.name); 4561 Log.i(TAG, buf.toString()); 4562 } 4563 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, 4564 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/); 4565 if (cph != null) { 4566 cph.noReleaseNeeded = true; 4567 results.add(cph); 4568 } 4569 } 4570 4571 try { 4572 ActivityManagerNative.getDefault().publishContentProviders( 4573 getApplicationThread(), results); 4574 } catch (RemoteException ex) { 4575 } 4576 } 4577 4578 public final IContentProvider acquireProvider( 4579 Context c, String auth, int userId, boolean stable) { 4580 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable); 4581 if (provider != null) { 4582 return provider; 4583 } 4584 4585 // There is a possible race here. Another thread may try to acquire 4586 // the same provider at the same time. When this happens, we want to ensure 4587 // that the first one wins. 4588 // Note that we cannot hold the lock while acquiring and installing the 4589 // provider since it might take a long time to run and it could also potentially 4590 // be re-entrant in the case where the provider is in the same process. 4591 IActivityManager.ContentProviderHolder holder = null; 4592 try { 4593 holder = ActivityManagerNative.getDefault().getContentProvider( 4594 getApplicationThread(), auth, userId, stable); 4595 } catch (RemoteException ex) { 4596 } 4597 if (holder == null) { 4598 Slog.e(TAG, "Failed to find provider info for " + auth); 4599 return null; 4600 } 4601 4602 // Install provider will increment the reference count for us, and break 4603 // any ties in the race. 4604 holder = installProvider(c, holder, holder.info, 4605 true /*noisy*/, holder.noReleaseNeeded, stable); 4606 return holder.provider; 4607 } 4608 4609 private final void incProviderRefLocked(ProviderRefCount prc, boolean stable) { 4610 if (stable) { 4611 prc.stableCount += 1; 4612 if (prc.stableCount == 1) { 4613 // We are acquiring a new stable reference on the provider. 4614 int unstableDelta; 4615 if (prc.removePending) { 4616 // We have a pending remove operation, which is holding the 4617 // last unstable reference. At this point we are converting 4618 // that unstable reference to our new stable reference. 4619 unstableDelta = -1; 4620 // Cancel the removal of the provider. 4621 if (DEBUG_PROVIDER) { 4622 Slog.v(TAG, "incProviderRef: stable " 4623 + "snatched provider from the jaws of death"); 4624 } 4625 prc.removePending = false; 4626 // There is a race! It fails to remove the message, which 4627 // will be handled in completeRemoveProvider(). 4628 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4629 } else { 4630 unstableDelta = 0; 4631 } 4632 try { 4633 if (DEBUG_PROVIDER) { 4634 Slog.v(TAG, "incProviderRef Now stable - " 4635 + prc.holder.info.name + ": unstableDelta=" 4636 + unstableDelta); 4637 } 4638 ActivityManagerNative.getDefault().refContentProvider( 4639 prc.holder.connection, 1, unstableDelta); 4640 } catch (RemoteException e) { 4641 //do nothing content provider object is dead any way 4642 } 4643 } 4644 } else { 4645 prc.unstableCount += 1; 4646 if (prc.unstableCount == 1) { 4647 // We are acquiring a new unstable reference on the provider. 4648 if (prc.removePending) { 4649 // Oh look, we actually have a remove pending for the 4650 // provider, which is still holding the last unstable 4651 // reference. We just need to cancel that to take new 4652 // ownership of the reference. 4653 if (DEBUG_PROVIDER) { 4654 Slog.v(TAG, "incProviderRef: unstable " 4655 + "snatched provider from the jaws of death"); 4656 } 4657 prc.removePending = false; 4658 mH.removeMessages(H.REMOVE_PROVIDER, prc); 4659 } else { 4660 // First unstable ref, increment our count in the 4661 // activity manager. 4662 try { 4663 if (DEBUG_PROVIDER) { 4664 Slog.v(TAG, "incProviderRef: Now unstable - " 4665 + prc.holder.info.name); 4666 } 4667 ActivityManagerNative.getDefault().refContentProvider( 4668 prc.holder.connection, 0, 1); 4669 } catch (RemoteException e) { 4670 //do nothing content provider object is dead any way 4671 } 4672 } 4673 } 4674 } 4675 } 4676 4677 public final IContentProvider acquireExistingProvider( 4678 Context c, String auth, int userId, boolean stable) { 4679 synchronized (mProviderMap) { 4680 final ProviderKey key = new ProviderKey(auth, userId); 4681 final ProviderClientRecord pr = mProviderMap.get(key); 4682 if (pr == null) { 4683 return null; 4684 } 4685 4686 IContentProvider provider = pr.mProvider; 4687 IBinder jBinder = provider.asBinder(); 4688 if (!jBinder.isBinderAlive()) { 4689 // The hosting process of the provider has died; we can't 4690 // use this one. 4691 Log.i(TAG, "Acquiring provider " + auth + " for user " + userId 4692 + ": existing object's process dead"); 4693 handleUnstableProviderDiedLocked(jBinder, true); 4694 return null; 4695 } 4696 4697 // Only increment the ref count if we have one. If we don't then the 4698 // provider is not reference counted and never needs to be released. 4699 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4700 if (prc != null) { 4701 incProviderRefLocked(prc, stable); 4702 } 4703 return provider; 4704 } 4705 } 4706 4707 public final boolean releaseProvider(IContentProvider provider, boolean stable) { 4708 if (provider == null) { 4709 return false; 4710 } 4711 4712 IBinder jBinder = provider.asBinder(); 4713 synchronized (mProviderMap) { 4714 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4715 if (prc == null) { 4716 // The provider has no ref count, no release is needed. 4717 return false; 4718 } 4719 4720 boolean lastRef = false; 4721 if (stable) { 4722 if (prc.stableCount == 0) { 4723 if (DEBUG_PROVIDER) Slog.v(TAG, 4724 "releaseProvider: stable ref count already 0, how?"); 4725 return false; 4726 } 4727 prc.stableCount -= 1; 4728 if (prc.stableCount == 0) { 4729 // What we do at this point depends on whether there are 4730 // any unstable refs left: if there are, we just tell the 4731 // activity manager to decrement its stable count; if there 4732 // aren't, we need to enqueue this provider to be removed, 4733 // and convert to holding a single unstable ref while 4734 // doing so. 4735 lastRef = prc.unstableCount == 0; 4736 try { 4737 if (DEBUG_PROVIDER) { 4738 Slog.v(TAG, "releaseProvider: No longer stable w/lastRef=" 4739 + lastRef + " - " + prc.holder.info.name); 4740 } 4741 ActivityManagerNative.getDefault().refContentProvider( 4742 prc.holder.connection, -1, lastRef ? 1 : 0); 4743 } catch (RemoteException e) { 4744 //do nothing content provider object is dead any way 4745 } 4746 } 4747 } else { 4748 if (prc.unstableCount == 0) { 4749 if (DEBUG_PROVIDER) Slog.v(TAG, 4750 "releaseProvider: unstable ref count already 0, how?"); 4751 return false; 4752 } 4753 prc.unstableCount -= 1; 4754 if (prc.unstableCount == 0) { 4755 // If this is the last reference, we need to enqueue 4756 // this provider to be removed instead of telling the 4757 // activity manager to remove it at this point. 4758 lastRef = prc.stableCount == 0; 4759 if (!lastRef) { 4760 try { 4761 if (DEBUG_PROVIDER) { 4762 Slog.v(TAG, "releaseProvider: No longer unstable - " 4763 + prc.holder.info.name); 4764 } 4765 ActivityManagerNative.getDefault().refContentProvider( 4766 prc.holder.connection, 0, -1); 4767 } catch (RemoteException e) { 4768 //do nothing content provider object is dead any way 4769 } 4770 } 4771 } 4772 } 4773 4774 if (lastRef) { 4775 if (!prc.removePending) { 4776 // Schedule the actual remove asynchronously, since we don't know the context 4777 // this will be called in. 4778 // TODO: it would be nice to post a delayed message, so 4779 // if we come back and need the same provider quickly 4780 // we will still have it available. 4781 if (DEBUG_PROVIDER) { 4782 Slog.v(TAG, "releaseProvider: Enqueueing pending removal - " 4783 + prc.holder.info.name); 4784 } 4785 prc.removePending = true; 4786 Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, prc); 4787 mH.sendMessage(msg); 4788 } else { 4789 Slog.w(TAG, "Duplicate remove pending of provider " + prc.holder.info.name); 4790 } 4791 } 4792 return true; 4793 } 4794 } 4795 4796 final void completeRemoveProvider(ProviderRefCount prc) { 4797 synchronized (mProviderMap) { 4798 if (!prc.removePending) { 4799 // There was a race! Some other client managed to acquire 4800 // the provider before the removal was completed. 4801 // Abort the removal. We will do it later. 4802 if (DEBUG_PROVIDER) Slog.v(TAG, "completeRemoveProvider: lost the race, " 4803 + "provider still in use"); 4804 return; 4805 } 4806 4807 // More complicated race!! Some client managed to acquire the 4808 // provider and release it before the removal was completed. 4809 // Continue the removal, and abort the next remove message. 4810 prc.removePending = false; 4811 4812 final IBinder jBinder = prc.holder.provider.asBinder(); 4813 ProviderRefCount existingPrc = mProviderRefCountMap.get(jBinder); 4814 if (existingPrc == prc) { 4815 mProviderRefCountMap.remove(jBinder); 4816 } 4817 4818 Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator(); 4819 while (iter.hasNext()) { 4820 ProviderClientRecord pr = iter.next(); 4821 IBinder myBinder = pr.mProvider.asBinder(); 4822 if (myBinder == jBinder) { 4823 iter.remove(); 4824 } 4825 } 4826 } 4827 4828 try { 4829 if (DEBUG_PROVIDER) { 4830 Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative." 4831 + "removeContentProvider(" + prc.holder.info.name + ")"); 4832 } 4833 ActivityManagerNative.getDefault().removeContentProvider( 4834 prc.holder.connection, false); 4835 } catch (RemoteException e) { 4836 //do nothing content provider object is dead any way 4837 } 4838 } 4839 4840 final void handleUnstableProviderDied(IBinder provider, boolean fromClient) { 4841 synchronized (mProviderMap) { 4842 handleUnstableProviderDiedLocked(provider, fromClient); 4843 } 4844 } 4845 4846 final void handleUnstableProviderDiedLocked(IBinder provider, boolean fromClient) { 4847 ProviderRefCount prc = mProviderRefCountMap.get(provider); 4848 if (prc != null) { 4849 if (DEBUG_PROVIDER) Slog.v(TAG, "Cleaning up dead provider " 4850 + provider + " " + prc.holder.info.name); 4851 mProviderRefCountMap.remove(provider); 4852 if (prc.client != null && prc.client.mNames != null) { 4853 for (String name : prc.client.mNames) { 4854 ProviderClientRecord pr = mProviderMap.get(name); 4855 if (pr != null && pr.mProvider.asBinder() == provider) { 4856 Slog.i(TAG, "Removing dead content provider: " + name); 4857 mProviderMap.remove(name); 4858 } 4859 } 4860 } 4861 if (fromClient) { 4862 // We found out about this due to execution in our client 4863 // code. Tell the activity manager about it now, to ensure 4864 // that the next time we go to do anything with the provider 4865 // it knows it is dead (so we don't race with its death 4866 // notification). 4867 try { 4868 ActivityManagerNative.getDefault().unstableProviderDied( 4869 prc.holder.connection); 4870 } catch (RemoteException e) { 4871 //do nothing content provider object is dead any way 4872 } 4873 } 4874 } 4875 } 4876 4877 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider, 4878 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) { 4879 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority); 4880 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid); 4881 4882 final ProviderClientRecord pcr = new ProviderClientRecord( 4883 auths, provider, localProvider, holder); 4884 for (String auth : auths) { 4885 final ProviderKey key = new ProviderKey(auth, userId); 4886 final ProviderClientRecord existing = mProviderMap.get(key); 4887 if (existing != null) { 4888 Slog.w(TAG, "Content provider " + pcr.mHolder.info.name 4889 + " already published as " + auth); 4890 } else { 4891 mProviderMap.put(key, pcr); 4892 } 4893 } 4894 return pcr; 4895 } 4896 4897 /** 4898 * Installs the provider. 4899 * 4900 * Providers that are local to the process or that come from the system server 4901 * may be installed permanently which is indicated by setting noReleaseNeeded to true. 4902 * Other remote providers are reference counted. The initial reference count 4903 * for all reference counted providers is one. Providers that are not reference 4904 * counted do not have a reference count (at all). 4905 * 4906 * This method detects when a provider has already been installed. When this happens, 4907 * it increments the reference count of the existing provider (if appropriate) 4908 * and returns the existing provider. This can happen due to concurrent 4909 * attempts to acquire the same provider. 4910 */ 4911 private IActivityManager.ContentProviderHolder installProvider(Context context, 4912 IActivityManager.ContentProviderHolder holder, ProviderInfo info, 4913 boolean noisy, boolean noReleaseNeeded, boolean stable) { 4914 ContentProvider localProvider = null; 4915 IContentProvider provider; 4916 if (holder == null || holder.provider == null) { 4917 if (DEBUG_PROVIDER || noisy) { 4918 Slog.d(TAG, "Loading provider " + info.authority + ": " 4919 + info.name); 4920 } 4921 Context c = null; 4922 ApplicationInfo ai = info.applicationInfo; 4923 if (context.getPackageName().equals(ai.packageName)) { 4924 c = context; 4925 } else if (mInitialApplication != null && 4926 mInitialApplication.getPackageName().equals(ai.packageName)) { 4927 c = mInitialApplication; 4928 } else { 4929 try { 4930 c = context.createPackageContext(ai.packageName, 4931 Context.CONTEXT_INCLUDE_CODE); 4932 } catch (PackageManager.NameNotFoundException e) { 4933 // Ignore 4934 } 4935 } 4936 if (c == null) { 4937 Slog.w(TAG, "Unable to get context for package " + 4938 ai.packageName + 4939 " while loading content provider " + 4940 info.name); 4941 return null; 4942 } 4943 try { 4944 final java.lang.ClassLoader cl = c.getClassLoader(); 4945 localProvider = (ContentProvider)cl. 4946 loadClass(info.name).newInstance(); 4947 provider = localProvider.getIContentProvider(); 4948 if (provider == null) { 4949 Slog.e(TAG, "Failed to instantiate class " + 4950 info.name + " from sourceDir " + 4951 info.applicationInfo.sourceDir); 4952 return null; 4953 } 4954 if (DEBUG_PROVIDER) Slog.v( 4955 TAG, "Instantiating local provider " + info.name); 4956 // XXX Need to create the correct context for this provider. 4957 localProvider.attachInfo(c, info); 4958 } catch (java.lang.Exception e) { 4959 if (!mInstrumentation.onException(null, e)) { 4960 throw new RuntimeException( 4961 "Unable to get provider " + info.name 4962 + ": " + e.toString(), e); 4963 } 4964 return null; 4965 } 4966 } else { 4967 provider = holder.provider; 4968 if (DEBUG_PROVIDER) Slog.v(TAG, "Installing external provider " + info.authority + ": " 4969 + info.name); 4970 } 4971 4972 IActivityManager.ContentProviderHolder retHolder; 4973 4974 synchronized (mProviderMap) { 4975 if (DEBUG_PROVIDER) Slog.v(TAG, "Checking to add " + provider 4976 + " / " + info.name); 4977 IBinder jBinder = provider.asBinder(); 4978 if (localProvider != null) { 4979 ComponentName cname = new ComponentName(info.packageName, info.name); 4980 ProviderClientRecord pr = mLocalProvidersByName.get(cname); 4981 if (pr != null) { 4982 if (DEBUG_PROVIDER) { 4983 Slog.v(TAG, "installProvider: lost the race, " 4984 + "using existing local provider"); 4985 } 4986 provider = pr.mProvider; 4987 } else { 4988 holder = new IActivityManager.ContentProviderHolder(info); 4989 holder.provider = provider; 4990 holder.noReleaseNeeded = true; 4991 pr = installProviderAuthoritiesLocked(provider, localProvider, holder); 4992 mLocalProviders.put(jBinder, pr); 4993 mLocalProvidersByName.put(cname, pr); 4994 } 4995 retHolder = pr.mHolder; 4996 } else { 4997 ProviderRefCount prc = mProviderRefCountMap.get(jBinder); 4998 if (prc != null) { 4999 if (DEBUG_PROVIDER) { 5000 Slog.v(TAG, "installProvider: lost the race, updating ref count"); 5001 } 5002 // We need to transfer our new reference to the existing 5003 // ref count, releasing the old one... but only if 5004 // release is needed (that is, it is not running in the 5005 // system process). 5006 if (!noReleaseNeeded) { 5007 incProviderRefLocked(prc, stable); 5008 try { 5009 ActivityManagerNative.getDefault().removeContentProvider( 5010 holder.connection, stable); 5011 } catch (RemoteException e) { 5012 //do nothing content provider object is dead any way 5013 } 5014 } 5015 } else { 5016 ProviderClientRecord client = installProviderAuthoritiesLocked( 5017 provider, localProvider, holder); 5018 if (noReleaseNeeded) { 5019 prc = new ProviderRefCount(holder, client, 1000, 1000); 5020 } else { 5021 prc = stable 5022 ? new ProviderRefCount(holder, client, 1, 0) 5023 : new ProviderRefCount(holder, client, 0, 1); 5024 } 5025 mProviderRefCountMap.put(jBinder, prc); 5026 } 5027 retHolder = prc.holder; 5028 } 5029 } 5030 5031 return retHolder; 5032 } 5033 5034 private void attach(boolean system) { 5035 sCurrentActivityThread = this; 5036 mSystemThread = system; 5037 if (!system) { 5038 ViewRootImpl.addFirstDrawHandler(new Runnable() { 5039 public void run() { 5040 ensureJitEnabled(); 5041 } 5042 }); 5043 android.ddm.DdmHandleAppName.setAppName("<pre-initialized>", 5044 UserHandle.myUserId()); 5045 RuntimeInit.setApplicationObject(mAppThread.asBinder()); 5046 IActivityManager mgr = ActivityManagerNative.getDefault(); 5047 try { 5048 mgr.attachApplication(mAppThread); 5049 } catch (RemoteException ex) { 5050 // Ignore 5051 } 5052 } else { 5053 // Don't set application object here -- if the system crashes, 5054 // we can't display an alert, we just want to die die die. 5055 android.ddm.DdmHandleAppName.setAppName("system_process", 5056 UserHandle.myUserId()); 5057 try { 5058 mInstrumentation = new Instrumentation(); 5059 ContextImpl context = new ContextImpl(); 5060 context.init(getSystemContext().mPackageInfo, null, this); 5061 Application app = Instrumentation.newApplication(Application.class, context); 5062 mAllApplications.add(app); 5063 mInitialApplication = app; 5064 app.onCreate(); 5065 } catch (Exception e) { 5066 throw new RuntimeException( 5067 "Unable to instantiate Application():" + e.toString(), e); 5068 } 5069 } 5070 5071 // add dropbox logging to libcore 5072 DropBox.setReporter(new DropBoxReporter()); 5073 5074 ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { 5075 public void onConfigurationChanged(Configuration newConfig) { 5076 synchronized (mPackages) { 5077 // We need to apply this change to the resources 5078 // immediately, because upon returning the view 5079 // hierarchy will be informed about it. 5080 if (applyConfigurationToResourcesLocked(newConfig, null)) { 5081 // This actually changed the resources! Tell 5082 // everyone about it. 5083 if (mPendingConfiguration == null || 5084 mPendingConfiguration.isOtherSeqNewer(newConfig)) { 5085 mPendingConfiguration = newConfig; 5086 5087 queueOrSendMessage(H.CONFIGURATION_CHANGED, newConfig); 5088 } 5089 } 5090 } 5091 } 5092 public void onLowMemory() { 5093 } 5094 public void onTrimMemory(int level) { 5095 } 5096 }); 5097 } 5098 5099 public static ActivityThread systemMain() { 5100 HardwareRenderer.disable(true); 5101 ActivityThread thread = new ActivityThread(); 5102 thread.attach(true); 5103 return thread; 5104 } 5105 5106 public final void installSystemProviders(List<ProviderInfo> providers) { 5107 if (providers != null) { 5108 installContentProviders(mInitialApplication, providers); 5109 } 5110 } 5111 5112 public int getIntCoreSetting(String key, int defaultValue) { 5113 synchronized (mPackages) { 5114 if (mCoreSettings != null) { 5115 return mCoreSettings.getInt(key, defaultValue); 5116 } else { 5117 return defaultValue; 5118 } 5119 } 5120 } 5121 5122 private static class EventLoggingReporter implements EventLogger.Reporter { 5123 @Override 5124 public void report (int code, Object... list) { 5125 EventLog.writeEvent(code, list); 5126 } 5127 } 5128 5129 private class DropBoxReporter implements DropBox.Reporter { 5130 5131 private DropBoxManager dropBox; 5132 5133 public DropBoxReporter() { 5134 dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE); 5135 } 5136 5137 @Override 5138 public void addData(String tag, byte[] data, int flags) { 5139 dropBox.addData(tag, data, flags); 5140 } 5141 5142 @Override 5143 public void addText(String tag, String data) { 5144 dropBox.addText(tag, data); 5145 } 5146 } 5147 5148 public static void main(String[] args) { 5149 SamplingProfilerIntegration.start(); 5150 5151 // CloseGuard defaults to true and can be quite spammy. We 5152 // disable it here, but selectively enable it later (via 5153 // StrictMode) on debug builds, but using DropBox, not logs. 5154 CloseGuard.setEnabled(false); 5155 5156 Environment.initForCurrentUser(); 5157 5158 // Set the reporter for event logging in libcore 5159 EventLogger.setReporter(new EventLoggingReporter()); 5160 5161 Security.addProvider(new AndroidKeyStoreProvider()); 5162 5163 Process.setArgV0("<pre-initialized>"); 5164 5165 Looper.prepareMainLooper(); 5166 5167 ActivityThread thread = new ActivityThread(); 5168 thread.attach(false); 5169 5170 if (sMainThreadHandler == null) { 5171 sMainThreadHandler = thread.getHandler(); 5172 } 5173 5174 AsyncTask.init(); 5175 5176 if (false) { 5177 Looper.myLooper().setMessageLogging(new 5178 LogPrinter(Log.DEBUG, "ActivityThread")); 5179 } 5180 5181 Looper.loop(); 5182 5183 throw new RuntimeException("Main thread loop unexpectedly exited"); 5184 } 5185} 5186