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